From a00acf8117550a4d3277d9f85e86593c11f851a3 Mon Sep 17 00:00:00 2001 From: Jean Guyader Date: Wed, 20 May 2009 17:54:55 +0000 Subject: [PATCH] Import svn://svn.sv.gnu.org/grub/trunk/grub2 r1998. --- AUTHORS | 23 + COPYING | 674 + ChangeLog | 14419 ++++++++++++++++ DISTLIST | 484 + INSTALL | 159 + Makefile.in | 396 + NEWS | 223 + README | 14 + THANKS | 37 + TODO | 13 + aclocal.m4 | 450 + autogen.sh | 13 + boot/i386/pc/boot.S | 489 + boot/i386/pc/cdboot.S | 175 + boot/i386/pc/diskboot.S | 387 + boot/i386/pc/lnxboot.S | 296 + boot/i386/pc/pxeboot.S | 39 + bus/pci.c | 66 + bus/usb/ohci.c | 608 + bus/usb/uhci.c | 675 + bus/usb/usb.c | 263 + bus/usb/usbhub.c | 193 + bus/usb/usbtrans.c | 212 + commands/blocklist.c | 122 + commands/boot.c | 50 + commands/cat.c | 88 + commands/cmp.c | 119 + commands/configfile.c | 78 + commands/crc.c | 66 + commands/date.c | 145 + commands/echo.c | 124 + commands/halt.c | 54 + commands/hdparm.c | 421 + commands/help.c | 103 + commands/hexdump.c | 136 + commands/i386/cpuid.c | 93 + commands/i386/pc/halt.c | 57 + commands/i386/pc/play.c | 217 + commands/i386/pc/pxecmd.c | 97 + commands/i386/pc/vbeinfo.c | 187 + commands/i386/pc/vbetest.c | 179 + commands/ieee1275/suspend.c | 48 + commands/loadenv.c | 257 + commands/ls.c | 245 + commands/lsmmap.c | 53 + commands/lspci.c | 171 + commands/read.c | 86 + commands/reboot.c | 56 + commands/search.c | 234 + commands/sleep.c | 112 + commands/terminal.c | 132 + commands/test.c | 70 + commands/usbtest.c | 160 + commands/videotest.c | 191 + conf/common.mk | 4303 +++++ conf/common.rmk | 499 + conf/i386-coreboot.mk | 2062 +++ conf/i386-coreboot.rmk | 215 + conf/i386-efi.mk | 1817 ++ conf/i386-efi.rmk | 195 + conf/i386-ieee1275.mk | 2012 +++ conf/i386-ieee1275.rmk | 214 + conf/i386-pc-cygwin-img-ld.sc | 53 + conf/i386-pc.mk | 3609 ++++ conf/i386-pc.rmk | 384 + conf/i386.mk | 192 + conf/i386.rmk | 16 + conf/powerpc-ieee1275.mk | 1542 ++ conf/powerpc-ieee1275.rmk | 185 + conf/sparc64-ieee1275.mk | 2315 +++ conf/sparc64-ieee1275.rmk | 292 + conf/x86_64-efi.mk | 1824 ++ conf/x86_64-efi.rmk | 197 + config.guess | 1552 ++ config.h.in | 131 + config.sub | 1681 ++ configure | 9915 +++++++++++ configure.ac | 444 + disk/ata.c | 861 + disk/ata_pthru.c | 109 + disk/dmraid_nvidia.c | 165 + disk/efi/efidisk.c | 859 + disk/fs_uuid.c | 137 + disk/host.c | 97 + disk/i386/pc/biosdisk.c | 390 + disk/ieee1275/nand.c | 216 + disk/ieee1275/ofdisk.c | 211 + disk/loopback.c | 258 + disk/lvm.c | 619 + disk/mdraid_linux.c | 233 + disk/memdisk.c | 117 + disk/raid.c | 723 + disk/raid5_recover.c | 72 + disk/raid6_recover.c | 216 + disk/scsi.c | 395 + disk/usbms.c | 393 + docs/fdl.texi | 452 + docs/grub.cfg | 69 + docs/grub.texi | 3967 +++++ docs/mdate-sh | 205 + docs/texinfo.tex | 8959 ++++++++++ font/font.c | 1026 ++ font/font_cmd.c | 77 + fs/affs.c | 570 + fs/afs.c | 636 + fs/cpio.c | 380 + fs/ext2.c | 922 + fs/fat.c | 888 + fs/fshelp.c | 315 + fs/hfs.c | 886 + fs/hfsplus.c | 975 ++ fs/i386/pc/pxe.c | 321 + fs/iso9660.c | 907 + fs/jfs.c | 885 + fs/minix.c | 613 + fs/ntfs.c | 1141 ++ fs/ntfscomp.c | 375 + fs/reiserfs.c | 1399 ++ fs/sfs.c | 621 + fs/tar.c | 2 + fs/udf.c | 929 + fs/ufs.c | 715 + fs/xfs.c | 833 + gencmdlist.sh | 18 + gendistlist.sh | 43 + genfslist.sh | 26 + geninit.sh | 75 + geninitheader.sh | 45 + genkernsyms.sh.in | 27 + genmk.rb | 359 + genmoddep.awk | 62 + genmodsrc.sh | 47 + genpartmaplist.sh | 26 + gensymlist.sh.in | 77 + hello/hello.c | 47 + hook/datehook.c | 106 + include/grub/acorn_filecore.h | 53 + include/grub/aout.h | 91 + include/grub/arg.h | 65 + include/grub/ata.h | 168 + include/grub/bitmap.h | 70 + include/grub/boot.h | 27 + include/grub/bufio.h | 28 + include/grub/cache.h | 28 + include/grub/device.h | 41 + include/grub/disk.h | 182 + include/grub/dl.h | 96 + include/grub/efi/api.h | 1136 ++ include/grub/efi/chainloader.h | 24 + include/grub/efi/console.h | 31 + include/grub/efi/console_control.h | 57 + include/grub/efi/disk.h | 33 + include/grub/efi/efi.h | 70 + include/grub/efi/pe32.h | 267 + include/grub/efi/time.h | 30 + include/grub/efi/uga_draw.h | 76 + include/grub/elf.h | 2333 +++ include/grub/elfload.h | 58 + include/grub/env.h | 72 + include/grub/err.h | 71 + include/grub/file.h | 72 + include/grub/font.h | 115 + include/grub/fs.h | 79 + include/grub/fshelp.h | 80 + include/grub/gpt_partition.h | 71 + include/grub/gzio.h | 28 + include/grub/hfs.h | 60 + include/grub/i386/at_keyboard.h | 57 + include/grub/i386/bsd.h | 232 + include/grub/i386/cmos.h | 74 + include/grub/i386/coreboot/boot.h | 1 + include/grub/i386/coreboot/console.h | 1 + include/grub/i386/coreboot/init.h | 28 + include/grub/i386/coreboot/kernel.h | 28 + include/grub/i386/coreboot/loader.h | 1 + include/grub/i386/coreboot/machine.h | 24 + include/grub/i386/coreboot/memory.h | 70 + include/grub/i386/coreboot/serial.h | 1 + include/grub/i386/coreboot/time.h | 1 + include/grub/i386/efi/kernel.h | 33 + include/grub/i386/efi/loader.h | 27 + include/grub/i386/efi/machine.h | 24 + include/grub/i386/efi/time.h | 24 + include/grub/i386/halt.h | 19 + include/grub/i386/ieee1275/console.h | 30 + include/grub/i386/ieee1275/ieee1275.h | 1 + include/grub/i386/ieee1275/kernel.h | 1 + include/grub/i386/ieee1275/loader.h | 33 + include/grub/i386/ieee1275/machine.h | 24 + include/grub/i386/ieee1275/memory.h | 1 + include/grub/i386/ieee1275/serial.h | 1 + include/grub/i386/ieee1275/time.h | 1 + include/grub/i386/io.h | 70 + include/grub/i386/kernel.h | 30 + include/grub/i386/linux.h | 277 + include/grub/i386/loader.h | 63 + include/grub/i386/pc/biosdisk.h | 126 + include/grub/i386/pc/boot.h | 81 + include/grub/i386/pc/chainloader.h | 33 + include/grub/i386/pc/console.h | 58 + include/grub/i386/pc/init.h | 50 + include/grub/i386/pc/kernel.h | 82 + include/grub/i386/pc/loader.h | 28 + include/grub/i386/pc/machine.h | 24 + include/grub/i386/pc/memory.h | 103 + include/grub/i386/pc/pxe.h | 318 + include/grub/i386/pc/serial.h | 67 + include/grub/i386/pc/time.h | 29 + include/grub/i386/pc/vbe.h | 277 + include/grub/i386/pc/vbeblit.h | 134 + include/grub/i386/pc/vbefill.h | 52 + include/grub/i386/pc/vbeutil.h | 43 + include/grub/i386/pc/vga.h | 34 + include/grub/i386/pci.h | 35 + include/grub/i386/pit.h | 26 + include/grub/i386/reboot.h | 19 + include/grub/i386/setjmp.h | 28 + include/grub/i386/time.h | 29 + include/grub/i386/tsc.h | 107 + include/grub/i386/types.h | 31 + include/grub/i386/vga_common.h | 40 + include/grub/ieee1275/ieee1275.h | 177 + include/grub/ieee1275/ofdisk.h | 25 + include/grub/kernel.h | 75 + include/grub/lib/LzFind.h | 130 + include/grub/lib/LzHash.h | 77 + include/grub/lib/LzmaDec.h | 246 + include/grub/lib/LzmaEnc.h | 95 + include/grub/lib/LzmaTypes.h | 151 + include/grub/lib/crc.h | 25 + include/grub/lib/datetime.h | 44 + include/grub/lib/envblk.h | 45 + include/grub/lib/hexdump.h | 25 + include/grub/loader.h | 44 + include/grub/lvm.h | 129 + include/grub/menu.h | 63 + include/grub/menu_viewer.h | 43 + include/grub/misc.h | 119 + include/grub/mm.h | 66 + include/grub/multiboot.h | 129 + include/grub/multiboot2.h | 64 + include/grub/multiboot_loader.h | 28 + include/grub/net.h | 72 + include/grub/normal.h | 198 + include/grub/ntfs.h | 182 + include/grub/parser.h | 67 + include/grub/partition.h | 113 + include/grub/pc_partition.h | 209 + include/grub/pci.h | 50 + include/grub/powerpc/ieee1275/biosdisk.h | 46 + include/grub/powerpc/ieee1275/console.h | 28 + include/grub/powerpc/ieee1275/ieee1275.h | 27 + include/grub/powerpc/ieee1275/kernel.h | 35 + include/grub/powerpc/ieee1275/loader.h | 32 + include/grub/powerpc/ieee1275/machine.h | 24 + include/grub/powerpc/ieee1275/memory.h | 24 + include/grub/powerpc/ieee1275/time.h | 29 + include/grub/powerpc/ieee1275/util/biosdisk.h | 27 + include/grub/powerpc/kernel.h | 32 + include/grub/powerpc/libgcc.h | 23 + include/grub/powerpc/setjmp.h | 27 + include/grub/powerpc/time.h | 28 + include/grub/powerpc/types.h | 32 + include/grub/raid.h | 86 + include/grub/rescue.h | 36 + include/grub/script.h | 287 + include/grub/scsi.h | 88 + include/grub/scsicmd.h | 122 + include/grub/setjmp.h | 33 + include/grub/sparc64/ieee1275/console.h | 28 + include/grub/sparc64/ieee1275/ieee1275.h | 27 + include/grub/sparc64/ieee1275/kernel.h | 30 + include/grub/sparc64/ieee1275/machine.h | 24 + include/grub/sparc64/ieee1275/time.h | 29 + include/grub/sparc64/libgcc.h | 19 + include/grub/sparc64/setjmp.h | 28 + include/grub/sparc64/time.h | 28 + include/grub/sparc64/types.h | 32 + include/grub/symbol.h | 46 + include/grub/term.h | 253 + include/grub/terminfo.h | 35 + include/grub/time.h | 40 + include/grub/tparm.h | 26 + include/grub/types.h | 208 + include/grub/usb.h | 207 + include/grub/usbdesc.h | 119 + include/grub/usbtrans.h | 107 + include/grub/util/getroot.h | 34 + include/grub/util/hostdisk.h | 27 + include/grub/util/lvm.h | 27 + include/grub/util/misc.h | 78 + include/grub/util/raid.h | 27 + include/grub/util/resolve.h | 35 + include/grub/video.h | 302 + include/grub/x86_64/efi/kernel.h | 33 + include/grub/x86_64/efi/loader.h | 32 + include/grub/x86_64/efi/machine.h | 24 + include/grub/x86_64/efi/time.h | 24 + include/grub/x86_64/kernel.h | 1 + include/grub/x86_64/linux.h | 19 + include/grub/x86_64/pci.h | 19 + include/grub/x86_64/setjmp.h | 27 + include/grub/x86_64/time.h | 29 + include/grub/x86_64/types.h | 31 + include/multiboot.h | 92 + include/multiboot2.h | 108 + install-sh | 519 + io/bufio.c | 205 + io/gzio.c | 1243 ++ kern/device.c | 136 + kern/disk.c | 576 + kern/dl.c | 725 + kern/efi/efi.c | 736 + kern/efi/init.c | 87 + kern/efi/mm.c | 429 + kern/elf.c | 464 + kern/env.c | 428 + kern/err.c | 134 + kern/file.c | 162 + kern/fs.c | 263 + kern/generic/millisleep.c | 39 + kern/generic/rtc_get_time_ms.c | 37 + kern/i386/coreboot/init.c | 156 + kern/i386/coreboot/mmap.c | 97 + kern/i386/coreboot/startup.S | 99 + kern/i386/dl.c | 111 + kern/i386/efi/init.c | 53 + kern/i386/efi/startup.S | 64 + kern/i386/halt.c | 42 + kern/i386/ieee1275/init.c | 32 + kern/i386/ieee1275/startup.S | 80 + kern/i386/loader.S | 243 + kern/i386/multiboot_mmap.c | 86 + kern/i386/pc/init.c | 229 + kern/i386/pc/lzma_decode.S | 677 + kern/i386/pc/lzo1x.S | 315 + kern/i386/pc/mmap.c | 63 + kern/i386/pc/startup.S | 2156 +++ kern/i386/pit.c | 56 + kern/i386/realmode.S | 178 + kern/i386/reboot.c | 31 + kern/i386/tsc.c | 74 + kern/ieee1275/cmain.c | 167 + kern/ieee1275/ieee1275.c | 602 + kern/ieee1275/init.c | 291 + kern/ieee1275/mmap.c | 71 + kern/ieee1275/openfw.c | 363 + kern/loader.c | 75 + kern/main.c | 152 + kern/misc.c | 1089 ++ kern/mm.c | 559 + kern/parser.c | 229 + kern/partition.c | 133 + kern/powerpc/cache.S | 48 + kern/powerpc/dl.c | 138 + kern/powerpc/ieee1275/startup.S | 64 + kern/rescue.c | 709 + kern/sparc64/cache.S | 43 + kern/sparc64/dl.c | 138 + kern/sparc64/ieee1275/init.c | 237 + kern/sparc64/ieee1275/openfw.c | 373 + kern/term.c | 331 + kern/time.c | 37 + kern/x86_64/dl.c | 121 + kern/x86_64/efi/callwrap.S | 96 + kern/x86_64/efi/startup.S | 87 + lib/LzFind.c | 774 + lib/LzmaDec.c | 1035 ++ lib/LzmaEnc.c | 2355 +++ lib/crc.c | 75 + lib/datetime.c | 49 + lib/efi/datetime.c | 79 + lib/envblk.c | 156 + lib/hexdump.c | 84 + lib/i386/datetime.c | 155 + loader/aout.c | 62 + loader/efi/appleloader.c | 208 + loader/efi/chainloader.c | 347 + loader/efi/chainloader_normal.c | 48 + loader/i386/bsd.c | 773 + loader/i386/bsd_normal.c | 102 + loader/i386/efi/linux.c | 972 ++ loader/i386/ieee1275/linux.c | 283 + loader/i386/linux.c | 606 + loader/i386/pc/chainloader.c | 164 + loader/i386/pc/chainloader_normal.c | 56 + loader/i386/pc/linux.c | 389 + loader/i386/pc/multiboot.c | 628 + loader/i386/pc/multiboot2.c | 101 + loader/i386/pc/multiboot_normal.c | 60 + loader/ieee1275/multiboot2.c | 126 + loader/linux_normal.c | 60 + loader/multiboot2.c | 461 + loader/multiboot_loader.c | 203 + loader/multiboot_loader_normal.c | 61 + loader/powerpc/ieee1275/linux.c | 343 + loader/powerpc/ieee1275/linux_normal.c | 60 + mkinstalldirs | 161 + normal/arg.c | 419 + normal/cmdline.c | 512 + normal/color.c | 148 + normal/command.c | 394 + normal/completion.c | 493 + normal/execute.c | 275 + normal/function.c | 125 + normal/i386/setjmp.S | 56 + normal/lexer.c | 364 + normal/main.c | 648 + normal/menu.c | 166 + normal/menu_entry.c | 1186 ++ normal/menu_text.c | 600 + normal/menu_viewer.c | 63 + normal/misc.c | 89 + normal/parser.y | 238 + normal/powerpc/setjmp.S | 84 + normal/script.c | 348 + normal/sparc64/setjmp.S | 38 + normal/x86_64/setjmp.S | 65 + partmap/acorn.c | 206 + partmap/amiga.c | 222 + partmap/apple.c | 259 + partmap/gpt.c | 200 + partmap/pc.c | 320 + partmap/sun.c | 223 + stamp-h.in | 1 + term/efi/console.c | 378 + term/gfxterm.c | 1181 ++ term/i386/pc/at_keyboard.c | 235 + term/i386/pc/console.c | 62 + term/i386/pc/serial.c | 627 + term/i386/pc/vesafb.c | 609 + term/i386/pc/vga.c | 519 + term/i386/pc/vga_text.c | 177 + term/i386/vga_common.c | 125 + term/ieee1275/ofconsole.c | 432 + term/terminfo.c | 187 + term/tparm.c | 768 + term/usb_keyboard.c | 257 + util/console.c | 387 + util/elf/grub-mkimage.c | 425 + util/getroot.c | 521 + util/grub-editenv.c | 269 + util/grub-emu.c | 226 + util/grub-fstest.c | 622 + util/grub-mkconfig.in | 217 + util/grub-mkconfig_lib.in | 178 + util/grub-mkdevicemap.c | 728 + util/grub-mkfont.c | 620 + util/grub-pe2elf.c | 514 + util/grub-probe.c | 387 + util/grub.d/00_header.in | 114 + util/grub.d/10_freebsd.in | 60 + util/grub.d/10_hurd.in | 85 + util/grub.d/10_linux.in | 158 + util/grub.d/10_windows.in | 83 + util/grub.d/30_os-prober.in | 89 + util/grub.d/40_custom.in | 3 + util/grub.d/README | 11 + util/hostdisk.c | 940 + util/hostfs.c | 168 + util/i386/efi/grub-install.in | 211 + util/i386/efi/grub-mkimage.c | 1124 ++ util/i386/pc/grub-install.in | 314 + util/i386/pc/grub-mkimage.c | 397 + util/i386/pc/grub-mkrescue.in | 176 + util/i386/pc/grub-setup.c | 751 + util/i386/pc/misc.c | 33 + util/ieee1275/grub-install.in | 233 + util/lvm.c | 50 + util/misc.c | 396 + util/powerpc/ieee1275/grub-mkrescue.in | 115 + util/powerpc/ieee1275/misc.c | 33 + util/raid.c | 112 + util/resolve.c | 267 + util/update-grub_lib.in | 23 + util/usb.c | 191 + video/bitmap.c | 256 + video/i386/pc/vbe.c | 1635 ++ video/i386/pc/vbeblit.c | 828 + video/i386/pc/vbefill.c | 177 + video/i386/pc/vbeutil.c | 177 + video/readers/jpeg.c | 748 + video/readers/png.c | 912 + video/readers/tga.c | 495 + video/video.c | 443 + 485 files changed, 169275 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 DISTLIST create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 THANKS create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100755 autogen.sh create mode 100644 boot/i386/pc/boot.S create mode 100644 boot/i386/pc/cdboot.S create mode 100644 boot/i386/pc/diskboot.S create mode 100644 boot/i386/pc/lnxboot.S create mode 100644 boot/i386/pc/pxeboot.S create mode 100644 bus/pci.c create mode 100644 bus/usb/ohci.c create mode 100644 bus/usb/uhci.c create mode 100644 bus/usb/usb.c create mode 100644 bus/usb/usbhub.c create mode 100644 bus/usb/usbtrans.c create mode 100644 commands/blocklist.c create mode 100644 commands/boot.c create mode 100644 commands/cat.c create mode 100644 commands/cmp.c create mode 100644 commands/configfile.c create mode 100644 commands/crc.c create mode 100644 commands/date.c create mode 100644 commands/echo.c create mode 100644 commands/halt.c create mode 100644 commands/hdparm.c create mode 100644 commands/help.c create mode 100644 commands/hexdump.c create mode 100644 commands/i386/cpuid.c create mode 100644 commands/i386/pc/halt.c create mode 100644 commands/i386/pc/play.c create mode 100644 commands/i386/pc/pxecmd.c create mode 100644 commands/i386/pc/vbeinfo.c create mode 100644 commands/i386/pc/vbetest.c create mode 100644 commands/ieee1275/suspend.c create mode 100644 commands/loadenv.c create mode 100644 commands/ls.c create mode 100644 commands/lsmmap.c create mode 100644 commands/lspci.c create mode 100644 commands/read.c create mode 100644 commands/reboot.c create mode 100644 commands/search.c create mode 100644 commands/sleep.c create mode 100644 commands/terminal.c create mode 100644 commands/test.c create mode 100644 commands/usbtest.c create mode 100644 commands/videotest.c create mode 100644 conf/common.mk create mode 100644 conf/common.rmk create mode 100644 conf/i386-coreboot.mk create mode 100644 conf/i386-coreboot.rmk create mode 100644 conf/i386-efi.mk create mode 100644 conf/i386-efi.rmk create mode 100644 conf/i386-ieee1275.mk create mode 100644 conf/i386-ieee1275.rmk create mode 100644 conf/i386-pc-cygwin-img-ld.sc create mode 100644 conf/i386-pc.mk create mode 100644 conf/i386-pc.rmk create mode 100644 conf/i386.mk create mode 100644 conf/i386.rmk create mode 100644 conf/powerpc-ieee1275.mk create mode 100644 conf/powerpc-ieee1275.rmk create mode 100644 conf/sparc64-ieee1275.mk create mode 100644 conf/sparc64-ieee1275.rmk create mode 100644 conf/x86_64-efi.mk create mode 100644 conf/x86_64-efi.rmk create mode 100644 config.guess create mode 100644 config.h.in create mode 100644 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100644 disk/ata.c create mode 100644 disk/ata_pthru.c create mode 100644 disk/dmraid_nvidia.c create mode 100644 disk/efi/efidisk.c create mode 100644 disk/fs_uuid.c create mode 100644 disk/host.c create mode 100644 disk/i386/pc/biosdisk.c create mode 100644 disk/ieee1275/nand.c create mode 100644 disk/ieee1275/ofdisk.c create mode 100644 disk/loopback.c create mode 100644 disk/lvm.c create mode 100644 disk/mdraid_linux.c create mode 100644 disk/memdisk.c create mode 100644 disk/raid.c create mode 100644 disk/raid5_recover.c create mode 100644 disk/raid6_recover.c create mode 100644 disk/scsi.c create mode 100644 disk/usbms.c create mode 100644 docs/fdl.texi create mode 100644 docs/grub.cfg create mode 100644 docs/grub.texi create mode 100755 docs/mdate-sh create mode 100644 docs/texinfo.tex create mode 100644 font/font.c create mode 100644 font/font_cmd.c create mode 100644 fs/affs.c create mode 100644 fs/afs.c create mode 100644 fs/cpio.c create mode 100644 fs/ext2.c create mode 100644 fs/fat.c create mode 100644 fs/fshelp.c create mode 100644 fs/hfs.c create mode 100644 fs/hfsplus.c create mode 100644 fs/i386/pc/pxe.c create mode 100644 fs/iso9660.c create mode 100644 fs/jfs.c create mode 100644 fs/minix.c create mode 100644 fs/ntfs.c create mode 100644 fs/ntfscomp.c create mode 100644 fs/reiserfs.c create mode 100644 fs/sfs.c create mode 100644 fs/tar.c create mode 100644 fs/udf.c create mode 100644 fs/ufs.c create mode 100644 fs/xfs.c create mode 100644 gencmdlist.sh create mode 100755 gendistlist.sh create mode 100644 genfslist.sh create mode 100644 geninit.sh create mode 100644 geninitheader.sh create mode 100644 genkernsyms.sh.in create mode 100644 genmk.rb create mode 100644 genmoddep.awk create mode 100644 genmodsrc.sh create mode 100644 genpartmaplist.sh create mode 100644 gensymlist.sh.in create mode 100644 hello/hello.c create mode 100644 hook/datehook.c create mode 100644 include/grub/acorn_filecore.h create mode 100644 include/grub/aout.h create mode 100644 include/grub/arg.h create mode 100644 include/grub/ata.h create mode 100644 include/grub/bitmap.h create mode 100644 include/grub/boot.h create mode 100644 include/grub/bufio.h create mode 100644 include/grub/cache.h create mode 100644 include/grub/device.h create mode 100644 include/grub/disk.h create mode 100644 include/grub/dl.h create mode 100644 include/grub/efi/api.h create mode 100644 include/grub/efi/chainloader.h create mode 100644 include/grub/efi/console.h create mode 100644 include/grub/efi/console_control.h create mode 100644 include/grub/efi/disk.h create mode 100644 include/grub/efi/efi.h create mode 100644 include/grub/efi/pe32.h create mode 100644 include/grub/efi/time.h create mode 100644 include/grub/efi/uga_draw.h create mode 100644 include/grub/elf.h create mode 100644 include/grub/elfload.h create mode 100644 include/grub/env.h create mode 100644 include/grub/err.h create mode 100644 include/grub/file.h create mode 100644 include/grub/font.h create mode 100644 include/grub/fs.h create mode 100644 include/grub/fshelp.h create mode 100644 include/grub/gpt_partition.h create mode 100644 include/grub/gzio.h create mode 100644 include/grub/hfs.h create mode 100644 include/grub/i386/at_keyboard.h create mode 100644 include/grub/i386/bsd.h create mode 100644 include/grub/i386/cmos.h create mode 100644 include/grub/i386/coreboot/boot.h create mode 100644 include/grub/i386/coreboot/console.h create mode 100644 include/grub/i386/coreboot/init.h create mode 100644 include/grub/i386/coreboot/kernel.h create mode 100644 include/grub/i386/coreboot/loader.h create mode 100644 include/grub/i386/coreboot/machine.h create mode 100644 include/grub/i386/coreboot/memory.h create mode 100644 include/grub/i386/coreboot/serial.h create mode 100644 include/grub/i386/coreboot/time.h create mode 100644 include/grub/i386/efi/kernel.h create mode 100644 include/grub/i386/efi/loader.h create mode 100644 include/grub/i386/efi/machine.h create mode 100644 include/grub/i386/efi/time.h create mode 100644 include/grub/i386/halt.h create mode 100644 include/grub/i386/ieee1275/console.h create mode 100644 include/grub/i386/ieee1275/ieee1275.h create mode 100644 include/grub/i386/ieee1275/kernel.h create mode 100644 include/grub/i386/ieee1275/loader.h create mode 100644 include/grub/i386/ieee1275/machine.h create mode 100644 include/grub/i386/ieee1275/memory.h create mode 100644 include/grub/i386/ieee1275/serial.h create mode 100644 include/grub/i386/ieee1275/time.h create mode 100644 include/grub/i386/io.h create mode 100644 include/grub/i386/kernel.h create mode 100644 include/grub/i386/linux.h create mode 100644 include/grub/i386/loader.h create mode 100644 include/grub/i386/pc/biosdisk.h create mode 100644 include/grub/i386/pc/boot.h create mode 100644 include/grub/i386/pc/chainloader.h create mode 100644 include/grub/i386/pc/console.h create mode 100644 include/grub/i386/pc/init.h create mode 100644 include/grub/i386/pc/kernel.h create mode 100644 include/grub/i386/pc/loader.h create mode 100644 include/grub/i386/pc/machine.h create mode 100644 include/grub/i386/pc/memory.h create mode 100644 include/grub/i386/pc/pxe.h create mode 100644 include/grub/i386/pc/serial.h create mode 100644 include/grub/i386/pc/time.h create mode 100644 include/grub/i386/pc/vbe.h create mode 100644 include/grub/i386/pc/vbeblit.h create mode 100644 include/grub/i386/pc/vbefill.h create mode 100644 include/grub/i386/pc/vbeutil.h create mode 100644 include/grub/i386/pc/vga.h create mode 100644 include/grub/i386/pci.h create mode 100644 include/grub/i386/pit.h create mode 100644 include/grub/i386/reboot.h create mode 100644 include/grub/i386/setjmp.h create mode 100644 include/grub/i386/time.h create mode 100644 include/grub/i386/tsc.h create mode 100644 include/grub/i386/types.h create mode 100644 include/grub/i386/vga_common.h create mode 100644 include/grub/ieee1275/ieee1275.h create mode 100644 include/grub/ieee1275/ofdisk.h create mode 100644 include/grub/kernel.h create mode 100644 include/grub/lib/LzFind.h create mode 100644 include/grub/lib/LzHash.h create mode 100644 include/grub/lib/LzmaDec.h create mode 100644 include/grub/lib/LzmaEnc.h create mode 100644 include/grub/lib/LzmaTypes.h create mode 100644 include/grub/lib/crc.h create mode 100644 include/grub/lib/datetime.h create mode 100644 include/grub/lib/envblk.h create mode 100644 include/grub/lib/hexdump.h create mode 100644 include/grub/loader.h create mode 100644 include/grub/lvm.h create mode 100644 include/grub/menu.h create mode 100644 include/grub/menu_viewer.h create mode 100644 include/grub/misc.h create mode 100644 include/grub/mm.h create mode 100644 include/grub/multiboot.h create mode 100644 include/grub/multiboot2.h create mode 100644 include/grub/multiboot_loader.h create mode 100644 include/grub/net.h create mode 100644 include/grub/normal.h create mode 100644 include/grub/ntfs.h create mode 100644 include/grub/parser.h create mode 100644 include/grub/partition.h create mode 100644 include/grub/pc_partition.h create mode 100644 include/grub/pci.h create mode 100644 include/grub/powerpc/ieee1275/biosdisk.h create mode 100644 include/grub/powerpc/ieee1275/console.h create mode 100644 include/grub/powerpc/ieee1275/ieee1275.h create mode 100644 include/grub/powerpc/ieee1275/kernel.h create mode 100644 include/grub/powerpc/ieee1275/loader.h create mode 100644 include/grub/powerpc/ieee1275/machine.h create mode 100644 include/grub/powerpc/ieee1275/memory.h create mode 100644 include/grub/powerpc/ieee1275/time.h create mode 100644 include/grub/powerpc/ieee1275/util/biosdisk.h create mode 100644 include/grub/powerpc/kernel.h create mode 100644 include/grub/powerpc/libgcc.h create mode 100644 include/grub/powerpc/setjmp.h create mode 100644 include/grub/powerpc/time.h create mode 100644 include/grub/powerpc/types.h create mode 100644 include/grub/raid.h create mode 100644 include/grub/rescue.h create mode 100644 include/grub/script.h create mode 100644 include/grub/scsi.h create mode 100644 include/grub/scsicmd.h create mode 100644 include/grub/setjmp.h create mode 100644 include/grub/sparc64/ieee1275/console.h create mode 100644 include/grub/sparc64/ieee1275/ieee1275.h create mode 100644 include/grub/sparc64/ieee1275/kernel.h create mode 100644 include/grub/sparc64/ieee1275/machine.h create mode 100644 include/grub/sparc64/ieee1275/time.h create mode 100644 include/grub/sparc64/libgcc.h create mode 100644 include/grub/sparc64/setjmp.h create mode 100644 include/grub/sparc64/time.h create mode 100644 include/grub/sparc64/types.h create mode 100644 include/grub/symbol.h create mode 100644 include/grub/term.h create mode 100644 include/grub/terminfo.h create mode 100644 include/grub/time.h create mode 100644 include/grub/tparm.h create mode 100644 include/grub/types.h create mode 100644 include/grub/usb.h create mode 100644 include/grub/usbdesc.h create mode 100644 include/grub/usbtrans.h create mode 100644 include/grub/util/getroot.h create mode 100644 include/grub/util/hostdisk.h create mode 100644 include/grub/util/lvm.h create mode 100644 include/grub/util/misc.h create mode 100644 include/grub/util/raid.h create mode 100644 include/grub/util/resolve.h create mode 100644 include/grub/video.h create mode 100644 include/grub/x86_64/efi/kernel.h create mode 100644 include/grub/x86_64/efi/loader.h create mode 100644 include/grub/x86_64/efi/machine.h create mode 100644 include/grub/x86_64/efi/time.h create mode 100644 include/grub/x86_64/kernel.h create mode 100644 include/grub/x86_64/linux.h create mode 100644 include/grub/x86_64/pci.h create mode 100644 include/grub/x86_64/setjmp.h create mode 100644 include/grub/x86_64/time.h create mode 100644 include/grub/x86_64/types.h create mode 100644 include/multiboot.h create mode 100644 include/multiboot2.h create mode 100755 install-sh create mode 100644 io/bufio.c create mode 100644 io/gzio.c create mode 100644 kern/device.c create mode 100644 kern/disk.c create mode 100644 kern/dl.c create mode 100644 kern/efi/efi.c create mode 100644 kern/efi/init.c create mode 100644 kern/efi/mm.c create mode 100644 kern/elf.c create mode 100644 kern/env.c create mode 100644 kern/err.c create mode 100644 kern/file.c create mode 100644 kern/fs.c create mode 100644 kern/generic/millisleep.c create mode 100644 kern/generic/rtc_get_time_ms.c create mode 100644 kern/i386/coreboot/init.c create mode 100644 kern/i386/coreboot/mmap.c create mode 100644 kern/i386/coreboot/startup.S create mode 100644 kern/i386/dl.c create mode 100644 kern/i386/efi/init.c create mode 100644 kern/i386/efi/startup.S create mode 100644 kern/i386/halt.c create mode 100644 kern/i386/ieee1275/init.c create mode 100644 kern/i386/ieee1275/startup.S create mode 100644 kern/i386/loader.S create mode 100644 kern/i386/multiboot_mmap.c create mode 100644 kern/i386/pc/init.c create mode 100644 kern/i386/pc/lzma_decode.S create mode 100644 kern/i386/pc/lzo1x.S create mode 100644 kern/i386/pc/mmap.c create mode 100644 kern/i386/pc/startup.S create mode 100644 kern/i386/pit.c create mode 100644 kern/i386/realmode.S create mode 100644 kern/i386/reboot.c create mode 100644 kern/i386/tsc.c create mode 100644 kern/ieee1275/cmain.c create mode 100644 kern/ieee1275/ieee1275.c create mode 100644 kern/ieee1275/init.c create mode 100644 kern/ieee1275/mmap.c create mode 100644 kern/ieee1275/openfw.c create mode 100644 kern/loader.c create mode 100644 kern/main.c create mode 100644 kern/misc.c create mode 100644 kern/mm.c create mode 100644 kern/parser.c create mode 100644 kern/partition.c create mode 100644 kern/powerpc/cache.S create mode 100644 kern/powerpc/dl.c create mode 100644 kern/powerpc/ieee1275/startup.S create mode 100644 kern/rescue.c create mode 100644 kern/sparc64/cache.S create mode 100644 kern/sparc64/dl.c create mode 100644 kern/sparc64/ieee1275/init.c create mode 100644 kern/sparc64/ieee1275/openfw.c create mode 100644 kern/term.c create mode 100644 kern/time.c create mode 100644 kern/x86_64/dl.c create mode 100644 kern/x86_64/efi/callwrap.S create mode 100644 kern/x86_64/efi/startup.S create mode 100644 lib/LzFind.c create mode 100644 lib/LzmaDec.c create mode 100644 lib/LzmaEnc.c create mode 100644 lib/crc.c create mode 100644 lib/datetime.c create mode 100644 lib/efi/datetime.c create mode 100644 lib/envblk.c create mode 100644 lib/hexdump.c create mode 100644 lib/i386/datetime.c create mode 100644 loader/aout.c create mode 100644 loader/efi/appleloader.c create mode 100644 loader/efi/chainloader.c create mode 100644 loader/efi/chainloader_normal.c create mode 100644 loader/i386/bsd.c create mode 100644 loader/i386/bsd_normal.c create mode 100644 loader/i386/efi/linux.c create mode 100644 loader/i386/ieee1275/linux.c create mode 100644 loader/i386/linux.c create mode 100644 loader/i386/pc/chainloader.c create mode 100644 loader/i386/pc/chainloader_normal.c create mode 100644 loader/i386/pc/linux.c create mode 100644 loader/i386/pc/multiboot.c create mode 100644 loader/i386/pc/multiboot2.c create mode 100644 loader/i386/pc/multiboot_normal.c create mode 100644 loader/ieee1275/multiboot2.c create mode 100644 loader/linux_normal.c create mode 100644 loader/multiboot2.c create mode 100644 loader/multiboot_loader.c create mode 100644 loader/multiboot_loader_normal.c create mode 100644 loader/powerpc/ieee1275/linux.c create mode 100644 loader/powerpc/ieee1275/linux_normal.c create mode 100755 mkinstalldirs create mode 100644 normal/arg.c create mode 100644 normal/cmdline.c create mode 100644 normal/color.c create mode 100644 normal/command.c create mode 100644 normal/completion.c create mode 100644 normal/execute.c create mode 100644 normal/function.c create mode 100644 normal/i386/setjmp.S create mode 100644 normal/lexer.c create mode 100644 normal/main.c create mode 100644 normal/menu.c create mode 100644 normal/menu_entry.c create mode 100644 normal/menu_text.c create mode 100644 normal/menu_viewer.c create mode 100644 normal/misc.c create mode 100644 normal/parser.y create mode 100644 normal/powerpc/setjmp.S create mode 100644 normal/script.c create mode 100644 normal/sparc64/setjmp.S create mode 100644 normal/x86_64/setjmp.S create mode 100644 partmap/acorn.c create mode 100644 partmap/amiga.c create mode 100644 partmap/apple.c create mode 100644 partmap/gpt.c create mode 100644 partmap/pc.c create mode 100644 partmap/sun.c create mode 100644 stamp-h.in create mode 100644 term/efi/console.c create mode 100644 term/gfxterm.c create mode 100644 term/i386/pc/at_keyboard.c create mode 100644 term/i386/pc/console.c create mode 100644 term/i386/pc/serial.c create mode 100644 term/i386/pc/vesafb.c create mode 100644 term/i386/pc/vga.c create mode 100644 term/i386/pc/vga_text.c create mode 100644 term/i386/vga_common.c create mode 100644 term/ieee1275/ofconsole.c create mode 100644 term/terminfo.c create mode 100644 term/tparm.c create mode 100644 term/usb_keyboard.c create mode 100644 util/console.c create mode 100644 util/elf/grub-mkimage.c create mode 100644 util/getroot.c create mode 100644 util/grub-editenv.c create mode 100644 util/grub-emu.c create mode 100644 util/grub-fstest.c create mode 100644 util/grub-mkconfig.in create mode 100644 util/grub-mkconfig_lib.in create mode 100644 util/grub-mkdevicemap.c create mode 100644 util/grub-mkfont.c create mode 100644 util/grub-pe2elf.c create mode 100644 util/grub-probe.c create mode 100644 util/grub.d/00_header.in create mode 100644 util/grub.d/10_freebsd.in create mode 100644 util/grub.d/10_hurd.in create mode 100644 util/grub.d/10_linux.in create mode 100644 util/grub.d/10_windows.in create mode 100644 util/grub.d/30_os-prober.in create mode 100644 util/grub.d/40_custom.in create mode 100644 util/grub.d/README create mode 100644 util/hostdisk.c create mode 100644 util/hostfs.c create mode 100644 util/i386/efi/grub-install.in create mode 100644 util/i386/efi/grub-mkimage.c create mode 100644 util/i386/pc/grub-install.in create mode 100644 util/i386/pc/grub-mkimage.c create mode 100644 util/i386/pc/grub-mkrescue.in create mode 100644 util/i386/pc/grub-setup.c create mode 100644 util/i386/pc/misc.c create mode 100644 util/ieee1275/grub-install.in create mode 100644 util/lvm.c create mode 100644 util/misc.c create mode 100644 util/powerpc/ieee1275/grub-mkrescue.in create mode 100644 util/powerpc/ieee1275/misc.c create mode 100644 util/raid.c create mode 100644 util/resolve.c create mode 100644 util/update-grub_lib.in create mode 100644 util/usb.c create mode 100644 video/bitmap.c create mode 100644 video/i386/pc/vbe.c create mode 100644 video/i386/pc/vbeblit.c create mode 100644 video/i386/pc/vbefill.c create mode 100644 video/i386/pc/vbeutil.c create mode 100644 video/readers/jpeg.c create mode 100644 video/readers/png.c create mode 100644 video/readers/tga.c create mode 100644 video/video.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..8de5c4d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,23 @@ +The following authors assigned copyright on their work to the Free +Software Foundation: + +Yoshinori K. Okuji designed and implemented the initial version. + +Jeroen Dekkers added initrd support, Multiboot support, and fixed bugs +in ext2fs. + +Marco Gerards added ext2fs support, grub-emu, a new command-line +engine, and fixed many bugs. + +Omniflux added terminfo and serial support. + +Vincent Pelletier added Sparc64 support. + +Hollis Blanchard implemented many parts of PowerPC support. + +Tomas Ebenlendr added the command chainloader into the normal mode, +fixed some bugs. + +Guillem Jover merged architecture-independent ELF support code. + +Vesa Jaaskelainen added VBE support. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..0ec24e9 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,14419 @@ +2009-02-21 Robert Millan + + Implement USB keyboard support (based on patch by Marco Gerards) + + * conf/i386-pc.rmk (pkglib_MODULES): Add `usb_keyboard.mod'. + (usb_keyboard_mod_SOURCES, usb_keyboard_mod_CFLAGS) + (usb_keyboard_mod_LDFLAGS): New variables. + + * term/usb_keyboard.c: New file. + +2009-02-14 Vladimir Serbinenko + + Corrected wrong declaration + + * kern/disk.c: corrected declaration of grub_disk_ata_pass_through. + +2009-02-14 Christian Franke + + * commands/lspci.c (grub_pci_classes): Add `SATA Controller'. + (grub_lspci_iter): Print class code and programming interface byte. + +2009-02-14 Christian Franke + + * gendistlist.sh: Ignore `.svn' directories. + +2009-02-14 Felix Zielcke + + * fs/fat.c: Add 2009 to Copyright line. + +2009-02-14 Christian Franke + + * commands/hdparm.c: New file. Provides `hdparm' command + which sends ATA commands via grub_disk_ata_pass_through (). + + * conf/i386-pc.rmk: Add ata_pthru.mod and hdparm.mod. + + * disk/ata.c: Include . Move + and to include/grub/ata.h. + (enum grub_ata_addressing_t): Move to include/grub/ata.h. + (GRUB_CDROM_SECTOR_SIZE): Remove. + (GRUB_ATA_*): Move to include/grub/ata.h. + (GRUB_ATAPI_*): Likewise. + (enum grub_ata_commands): Likewise. + (enum grub_ata_timeout_milliseconds): Likewise. + (struct grub_ata_device): Likewise. + (grub_ata_regset): Likewise. + (grub_ata_regget): Likewise. + (grub_ata_regset2): Likewise. + (grub_ata_regget2): Likewise. + (grub_ata_check_ready): Likewise. + (grub_ata_wait_not_busy): Remove static, exported in + include/grub/ata.h. + (grub_ata_wait_drq): Likewise. + (grub_ata_pio_read): Likewise. + + * disk/ata_pthru.c: New file. Provides grub_ata_pass_through () + function for hdparm.mod. + + * include/grub/ata.h: New file, contains declarations from + disk/ata.c. + (enum grub_ata_commands): Add new commands for commands/hdparm.c. + + * include/grub/disk.h (grub_disk_ata_pass_through_parms): New struct. + (grub_disk_ata_pass_through): New exported variable. + + * kern/disk.c (grub_disk_ata_pass_through): New variable. + +2009-02-13 Colin D Bennett + + Support multiple fallback entries, and provide an API to support + executing default+fallback menu entries. Renamed the `terminal' menu + viewer to `text'. + + * include/grub/normal.h (grub_normal_text_menu_viewer): New global + variable declaration. + (grub_menu_execute_callback): New structure declaration. + (grub_menu_execute_callback_t): New typedef. + (grub_menu_execute_with_fallback): New function declaration. + (grub_menu_get_entry): Likewise. + (grub_menu_get_timeout): Likewise. + (grub_menu_set_timeout): Likewise. + + * normal/main.c (GRUB_MOD_INIT(normal)): Refer to new variable name. + + * normal/menu.c (grub_wait_after_message): Moved to + `normal/menu_text.c'. + (draw_border): Likewise. + (print_message): Likewise. + (print_entry): Likewise. + (print_entries): Likewise. + (grub_menu_init_page): Likewise. + (get_entry_number): Likewise. + (print_timeout): Likewise. + (run_menu): Likewise. + (grub_menu_execute_entry): Likewise. + (show_text_menu): Likewise. + (get_and_remove_first_entry_number): New function. + (grub_menu_execute_with_fallback): Likewise. + (get_entry): Renamed to ... + (grub_menu_get_entry): .. this and made it global. + (get_timeout): Renamed to ... + (grub_menu_get_timeout): ... this and made it global. + (set_timeout): Renamed to ... + (grub_menu_set_timeout): ... this and made it global. + (grub_normal_terminal_menu_viewer): Renamed to ... + (grub_normal_text_menu_viewer): ... this. + + * normal/menu_text.c: New file. Extracted text-menu-specific code + from normal/menu.c. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add `normal/menu_text.c'. + (normal_mod_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/i386-pc.rmk, (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + +2009-02-11 Robert Millan + + * util/grub.d/00_header.in: Update old reference to `font' command. + +2009-02-10 Felix Zielcke + + * fs/fat.c (grub_fat_mount): Fix wrong comparison. + + Based on patch from Javier Martín. + +2009-02-09 Felix Zielcke + + * conf/common.rmk (grub_probe_SOURCES): Move fs/ext2.c before fs/fat.c + to avoid false posivites with FAT. + (grub_fstest_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2009-02-09 Felix Zielcke + + * fs/fat.c (grub_fat_mount): Try to avoid false positives by checking + bpb.version_specific.fat12_or_fat16.fstype and + bpb.version_specific.fat32.fstype. + +2009-02-08 Robert Millan + + * fs/tar.c: Replace "fs/cpio.c" with "cpio.c". + +2009-02-08 Robert Millan + + * Makefile.in (host_os, host_cpu): New variables. + (target_os): Remove. Update all users. + +2009-02-08 Marco Gerards + + * Makefile.in (enable_grub_emu_usb): New variable. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/scsi.c'. + (grub_emu_SOURCES) [grub_emu_SOURCES]: Add `disk/usbms.c', + `util/usb.c', `bus/usb/usb.c' and `commands/usbtest.c'. + (grub_emu_LDFLAGS): Add `$(LIBUSB)'. + (pkglib_MODULES): Add `usb.mod', `uhci.mod', `ohci.mod', + `usbtest.mod' and `usbms.mod'. + (usb_mod_SOURCES, usb_mod_CFLAGS, usb_mod_LDFLAGS) + (usbtest_mod_SOURCES, usbtest_mod_CFLAGS, usbtest_mod_LDFLAGS) + (uhci_mod_SOURCES, uhci_mod_CFLAGS, uhci_mod_LDFLAGS, + (ohci_mod_SOURCES, ohci_mod_CFLAGS, ohci_mod_LDFLAGS) + (usbms_mod_SOURCES, usbms_mod_CFLAGS, usbms_mod_LDFLAGS): New + variables. + + * disk/usbms.c: New file. + + * include/grub/usb.h: Likewise. + + * include/grub/usbtrans.h: Likewise. + + * include/grub/usbdesc.h: Likewise. + + * bus/usb/usbtrans.c: Likewise. + + * bus/usb/ohci.c: Likewise. + + * bus/usb/uhci.c: Likewise. + + * bus/usb/usbhub.c: Likewise. + + * bus/usb/usb.c: Likewise. + + * commands/usbtest.c: Likewise. + + * util/usb.c: Likewise. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_IO'. + + * configure.ac: Test for libusb presence. + + * util/grub-emu.c (main) [HAVE_LIBUSB_H]: Call `grub_libusb_init'. + +2009-02-08 Vesa Jääskeläinen + + * kern/mm.c: Add more comments. + +2009-02-08 Robert Millan + + Patch from Javier Martín. + * fs/ext2.c (EXT2_DRIVER_SUPPORTED_INCOMPAT): Add + `EXT4_FEATURE_INCOMPAT_FLEX_BG'. + +2009-02-08 Robert Millan + + * fs/cpio.c: Split tar functionality to ... + * fs/tar.c: ... here (new file). Update all users. + +2009-02-07 Robert Millan + + * fs/ext2.c (grub_ext2_mount): Avoid mounting filesystems with + backward-incompatible features. + + Based on patch from Javier Martín, with some adjustments. + +2009-02-07 Michael Scherer + + * fs/hfs.c (grub_hfsplus_iterate_dir): Treat hfs+ as case insensitive. + +2009-02-07 Robert Millan + + * conf/common.rmk (grub_probe_SOURCES, grub_fstest_SOURCES): Move + position of `disk/lvm.c' to ensure grub_init_all() always picks it + after the RAID stuff. + +2009-02-05 Vesa Jääskeläinen + + Fixes problem when running vbetest command as reported by + Vladimir Serbinenko . + + * (grub_vbe_set_video_mode): Fixed problem with text modes. + +2009-02-04 Felix Zielcke + + util/getroot.c (grub_util_get_grub_dev): Add support for /dev/mdNpN and + /dev/md/NpN style mdraid devices. + +2009-02-03 Felix Zielcke + + * util/unifont2pff.rb: Remove. + +2009-02-03 Felix Zielcke + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add a missing trailing + `#'. + +2009-02-03 Felix Zielcke + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/menu_viewer.c'. + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2009-02-02 Christian Franke + + * lib/hexdump.c (hexdump): Print at most 3 lines if data is identical. + +2009-02-01 Felix Zielcke + + * INSTALL: Note that we now require at least autoconf 2.59 and + that LZO is optional. + +2009-02-01 Vesa Jääskeläinen + + Base on patch on bug #24154 created by Tomas Tintera + . + + * video/i386/pc/vbe.c (grub_video_vbe_scroll): Fix downward scrolling. + +2009-02-01 Vesa Jääskeläinen + + Based on patch on bug #25318 created by Bernhard Rosenkraenzer + . + + * normal/parser.y (script_init): Add missing semicolon. + +2009-01-31 Colin D Bennett + + * normal/main.c: Add include to grub/menu_viewer.h. + (free_menu_entry_classes): Added. + (grub_normal_menu_addentry): Added class property handling. + (grub_normal_execute): Changed to use new menu viewer for menu viewing. + (GRUB_MOD_INIT(normal)): Added register for text based menu viewer. + + * normal/menu_viewer.c: New file. + + * normal/menu.c (run_menu_entry): Renamed to ... + (grub_menu_execute_entry): ... this and made it as global. + (grub_menu_run): Renamed to ... + (show_text_menu): ... this and made it local. + (show_text_menu): Adapt to new function names. + (grub_normal_terminal_menu_viewer): New global variable. + + * include/grub/menu.h: New file. + + * include/grub/menu_viewer.h: New file. + + * include/grub/normal.h: Added include to grub/menu.h. + (grub_menu_entry): Moved to include/grub/menu.h. + (grub_menu_entry_t): Likewise. + (grub_menu): Likewise. + (grub_menu_t): Likewise. + (grub_normal_terminal_menu_viewer): Added. + (grub_menu_execute_entry): Likewise. + (grub_menu_run): Removed. + + * DISTLIST: Added include/grub/menu.h. + Added include/grub/menu_viewer.h. + Added normal/menu_viewer.c. + +2009-01-31 Vesa Jääskeläinen + + * normal/execute.c (grub_script_execute_menuentry): Changed to use + arglist for menutitle arguments. + + * normal/main.c (grub_normal_menu_addentry): Likewise. + + * normal/parser.y (menuentry): Likewise. + + * normal/script.c (grub_script_create_cmdmenu): Likewise. + + * include/grub/script.h (grub_script_cmd_menuentry): Likewise. + (grub_script_create_cmdmenu): Likewise. + + * include/grub/normal.h (grub_normal_menu_addentry): Likewise. + + * conf/i386-pc.rmk (normal_mod_SOURCES): Adapt Colin D Bennett's + changes. + + * conf/x86_64-efi.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-coreboot.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-efi.rmk (normal_mod_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (normal_mod_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (normal_mod_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (normal_mod_SOURCES): Likewise. + +2009-01-30 Christian Franke + + * normal/arg.c (grub_arg_show_help): Add indentation if '\n' appears + in option help text. + +2009-01-27 Pavel Roskin + + * disk/fs_uuid.c (search_fs_uuid): Ignore case of the UUID. + +2009-01-27 Vesa Jääskeläinen + + * commands/lsmmap.c: Add include to grub/machine/memory.h. + + * fs/i386/pc/pxe.c (grub_pxefs_open): Fix sign problem. + + * term/i386/pc/at_keyboard.c (GRUB_MOD_FINI(at_keyboard)): Use proper + unregister function. + +2009-01-27 Vesa Jääskeläinen + + * disk/scsi.c (grub_scsi_read): Fix sign problem. + + * term/i386/pc/vga_text.c (grub_vga_text_init_fini). Fix declaration. + + * util/grub-mkfont.c (usage): Fix typo. + + * util/elf/grub-mkimage.c (load_modules): Fix warning. + +2009-01-26 Daniel Mierswa + + * fs/fat.c (grub_fat_uuid): Fix shift of the first two bytes. + + * commands/search.c (search_fs_uuid): Ignore case of the UUID. + + * kern/misc.c (grub_strcasecmp): New function. + (grub_strcasecmp): Use grub_size_t instead of int for length. + Fix return value. + * include/grub/misc.h: Update function prototypes. + +2009-01-26 Robert Millan + + * configure.ac: Fix cross-compilation check. + +2009-01-22 Christian Franke + + * kern/misc.c (grub_vsprintf): Fix size and termination of `format2' + (precision) digit string. Allow `.format2' without `format1' (width). + Limit input chars for `%s' output to `format2' if specified. This is + compatible with standard printf (). + +2009-01-22 Christian Franke + + * disk/ata.c (grub_ata_wait_status): Replace by ... + (grub_ata_wait_not_busy): ... this function. Checks only BSY bit, + other status bits may be invalid while BSY is asserted. + (grub_ata_check_ready): New function. + (grub_ata_cmd): Removed. + (grub_ata_wait_drq): New function. + (grub_ata_strncpy): Remove inline. + (grub_ata_pio_read): Reduce to actual block transfer. BSY wait + and error check now done by grub_ata_wait_drq (). + (grub_ata_pio_write): Likewise. + (grub_atapi_identify): Set DEV before check for !BSY. Use + grub_ata_wait_drq () to wait for data. + (grub_ata_device_initialize): Add status register check to + detect missing SATA slave devices. Add debug messages. + (grub_atapi_wait_drq): Use grub_ata_wait_not_busy (). + (grub_atapi_packet): Set DEV before check for !BSY. Replace + transfer loop by grub_ata_pio_write (). + (grub_ata_identify): Set DEV before check for !BSY. Use + grub_ata_wait_drq () to wait for data. + (grub_ata_setaddress): Set DEV before check for !BSY. + (grub_ata_readwrite): Remove duplicate code, handle batch/rest and + read/write in one loop. Fix invalid command on write. Fix incomplete + command on (size % batch) == 0. Add missing error check after write of + last block. Add debug messages. + (grub_atapi_read): Replace transfer loop by grub_ata_pio_read (). + +2009-01-19 Christian Franke + + * disk/ata.c (GRUB_ATAPI_REG_*): New defines. + (GRUB_ATAPI_IREASON_*): Likewise. + (grub_ata_pio_write): Fix timeout error return. + (grub_atapi_identify): Add grub_ata_wait () after cmd. + (grub_atapi_wait_drq): New function. + (grub_atapi_packet): New parameter `size'. + Use grub_atapi_wait_drq () and direct write instead of + grub_ata_pio_write (). + (grub_atapi_read): Replace grub_ata_pio_read () by a loop which + reads the number of bytes requested by the device for each DRQ + assertion. + (grub_atapi_write): Remove old implementation, return not + implemented instead. + +2009-01-19 Christian Franke + + * disk/scsi.c (grub_scsi_read10): Use scsi->blocksize instead + of 512 to calculate data size. + (grub_scsi_read12): Likewise. + (grub_scsi_write10): Likewise. + (grub_scsi_write12): Likewise. + (grub_scsi_read): Adjust size according to blocksize. + Add checks for invalid blocksize and unaligned transfer. + +2009-01-19 Vesa Jääskeläinen + + * font/font.c (grub_font_loader_init): Re-position unknown glyph. + + * term/gfxterm.c (write_char): Fix background rendering for wide + width glyphs. + +2009-01-19 Robert Millan + + * config.guess: Update to latest version from config git. + * config.sub: Likewise. + +2009-01-17 Felix Zielcke + + * Makefile.in: Change font compilation to use new grub-mkfont instead + of java version. + + * util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: Remove. + * util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise. + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise. + +2009-01-16 Christian Franke + + * disk/ata.c (enum grub_ata_commands): Remove EXEC_DEV_DIAGNOSTICS. + (enum grub_ata_timeout_milliseconds): New enum. + (grub_ata_wait_status): Add parameter milliseconds. + (grub_ata_cmd): Remove variable `err'. Remove wait for !DRQ to allow + recovery from timed-out commands. + (grub_ata_pio_read): Add parameter milliseconds. Fix error return, + return grub_errno instead of REG_ERROR. + (grub_ata_pio_write): Add parameter milliseconds. + (grub_atapi_identify): Fix size of ATAPI IDENTIFY sector. + Pass milliseconds to grub_ata_wait_status () and + grub_ata_pio_read (). + (grub_atapi_packet): Pass milliseconds to grub_ata_pio_write (). + (grub_ata_identify): Remove variable `ataerr'. Pass milliseconds to + grub_ata_wait_status (). Fix IDENTIFY timeout check. + (grub_ata_device_initialize): Remove EXECUTE DEVICE DIAGNOSTICS. + It is not suitable for device detection, because DEV bit is ignored, + the command may run too long, and not all devices set the signature + properly. + (grub_ata_pciinit): Clear grub_errno before grub_ata_device_initialize (). + (grub_ata_setaddress): Pass milliseconds to grub_ata_wait_status (). + Fix device selection, DEV bit must be set first to address the registers + of the correct device. + (grub_ata_readwrite): Pass milliseconds to grub_ata_wait_status () and + grub_ata_pio_read/write (). + (grub_atapi_read): Pass milliseconds to grub_ata_pio_read (). + (grub_atapi_write): Pass milliseconds to grub_ata_pio_write (). + +2009-01-13 Carles Pina i Estany + + * util/grub-editenv.c (main): Use fseeko(), not fseek(). + +2009-01-13 Bean + + * util/grub-mkfont.c (write_font): forget to remove some debug code. + +2009-01-13 Bean + + * Makefile.in: (enable_grub_mkfont): New variable. + (freetype_cflags): Likewise. + (freetype_libs): Likewise. + + * common.rmk (bin_UTILITIES): Add `grub-mkfont' if requested. + (grub_mkfont_SOURCES): New variable. + (grub_mkfont_CFLAGS): Likewise. + (grub_mkfont_LDFLAGS): Likewise. + + * configure.ac (--enable-grub-mkfont): New option. Check for freetype2 + library if `--enable-grub-mkfont' is requested. + (enable_grub_mkfont): New variable. + (freetype_cflags): Likewise. + (freetype_libs): Likewise. + + * util/grub-mkfont.c: New file. + +2009-01-12 Christian Franke + + * disk/ata.c (grub_ata_pciinit): Fix bit numbers of compatibility + mode check. Fix setting of compat_use[]. + +2009-01-10 Robert Millan + + Update a few copyright years which we forgot to do in 2008 (only for + files whose changes made in 2008 were copyright-significant) + + * Makefile.in: Add 2008 to Copyright line. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/efi/efidisk.c: Likewise. + * kern/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/mm.c: Likewise. + * kern/efi/mm.c: Likewise. + * boot/i386/pc/boot.S: Likewise. + * genfslist.sh: Likewise. + * fs/iso9660.c: Likewise. + * fs/hfs.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/ufs.c: Likewise. + * gensymlist.sh.in: Likewise. + * genkernsyms.sh.in: Likewise. + * include/grub/misc.h: Likewise. + * include/grub/types.h: Likewise. + * include/grub/symbol.h: Likewise. + * include/grub/elf.h: Likewise. + * include/grub/kernel.h: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/dl.h: Likewise. + * include/grub/i386/linux.h: Likewise. + * include/grub/i386/pc/biosdisk.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/util/misc.h: Likewise. + * normal/execute.c: Likewise. + * normal/arg.c: Likewise. + * normal/completion.c: Likewise. + * normal/lexer.c: Likewise. + * normal/parser.y: Likewise. + * normal/misc.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/hexdump.c: Likewise. + * commands/terminal.c: Likewise. + * commands/ls.c: Likewise. + * commands/help.c: Likewise. + * partmap/pc.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * term/efi/console.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * util/lvm.c: Likewise. + * util/console.c: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/raid.c: Likewise. + +2009-01-06 Vesa Jääskeläinen + + * commands/videotest.c: Removed include to grub/machine/memory.h. + + * conf/i386-pc.rmk (pkglib_MODULES): Removed video.mod, gfxterm.mod, + videotest.mod, bitmap.mod, tga.mod, jpeg.mod, png.mod. + (video_mod_SOURCES): Removed. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (bitmap_mod_SOURCES): Likewise. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + (jpeg_mod_SOURCES): Likewise. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + (png_mod_SOURCES): Likewise. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + + * conf/common.rmk (pkglib_MODULES): Added video.mod, videotest.mod, + bitmap.mod, tga.mod, jpeg.mod, png.mod, font.mod, gfxterm.mod + (video_mod_SOURCES): Added. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (bitmap_mod_SOURCES): Likewise. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + (jpeg_mod_SOURCES): Likewise. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + (png_mod_SOURCES): Likewise. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + + * term/gfxterm.c: Removed include to grub/machine/memory.h, + grub/machine/console.h. + +2009-01-04 Jerone Young + + Make on screen instructions clearer + + Based on patch created by Jidanni + + * normal/menu.c: print clearer instructions on the screen + +2009-01-02 Colin D Bennett + + New font engine. + + Additional changes by Vesa Jääskeläinen to adapt to + build system and fixed gfxterm.c to work with different sized fonts. + + * configure.ac: Changed UNIFONT_HEX to UNIFONT_BDF. + + * configure: Re-generated. + + * DISTLIST: Removed font/manager.c. + Added font/font.c. + Added font/font_cmd.c. + + * Makefile.in: Changed UNIFONT_HEX to UNIFONT_BDF. Added Font tool + compilation. + + * include/grub/misc.h (grub_utf8_to_ucs4): Changed prototype. Changed users. + + * kern/misc.c (grub_utf8_to_ucs4): Changed prototype. + + * kern/term.c: Changed users of grub_utf8_to_ucs4. + + * normal/menu.c: Likewise. + + * conf/common.rmk (font_mod_SOURCES): Removed font/manager.c. + (font_mod_SOURCES): Added font/font_cmd.c, font/font.c. + + * include/grub/font.h: Replaced with new file. + + * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_ALPHA): Changed value. + (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED): Likewise. + (GRUB_VIDEO_MODE_TYPE_COLOR_MASK): Likewise. + (GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP): Added. + (grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED. + (grub_video_mode_info): Added bg_red, bg_green, bg_blue, bg_alpha, + fg_red, fg_green, fg_blue, fg_alpha. + (grub_video_adapter): Removed blit_glyph. + (grub_video_blit_glyph): Removed. + + * font/manager.c: Removed file. + + * font/font.c: New file. + + * font/font_cmd.c: Likewise. + + * video/video.c (grub_video_blit_glyph): Removed. + + * video/i386/pc/vbe.c (grub_video_vbe_map_rgb): Added 1-bit support. + (grub_video_vbe_map_rgba): Likewise. + (grub_video_vbe_unmap_color_int): Likewise. + (grub_video_vbe_blit_glyph): Removed. + (grub_video_vbe_adapter): Removed blit_glyph. + + * video/i386/pc/vbeutil.c (get_data_ptr): Added 1-bit support. + (get_pixel): Likewise. + (set_pixel): Likewise. + + * commands/videotest.c (grub_cmd_videotest): Added more tests for fonts. + + * term/gfxterm.c: Adapted to new font engine. + + * term/i386/pc/vesafb.c: Marked as deprecated. Made it compile. + + * term/i386/pc/vga.c: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: New file. + + * util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise. + + * util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise. + + * util/grub.d/00_header.in: Changed to use new loadfont command. + + * util/grub-mkconfig_lib.in: Changed font extension. + +2008-12-28 Felix Zielcke + + * util/getroot.c (grub_util_get_grub_dev): Add support for + /dev/md/dNNpNN style partitionable mdraid devices. + +2008-12-12 Alex Smith + + * fs/i386/pc/pxe.c (grub_pxefs_open): Handle the one open connection + at a time limit of the PXE TFTP API correctly. + (grub_pxefs_close): Likewise. + +2008-11-29 Robert Millan + + * disk/ata.c (grub_ata_pciinit): Handle errors raised by + grub_ata_device_initialize() calls. + +2008-11-28 Krzysztof Smiechowicz + + * fs/affs.c (grub_affs_iterate_dir): Return failure when directory + iteration failed. + * fs/sfs.c (grub_sfs_iterate_dir): Likewise. + +2008-11-28 Robert Millan + + Fix build on powerpc-ieee1275. Based on patch created by + Manoel Abranches . + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/ieee1275/mmap.c'. + * include/grub/powerpc/ieee1275/memory.h: New file. + + Provide grub-install on coreboot. + * conf/i386-coreboot.rmk (sbin_SCRIPTS): Add `grub-install'. + (grub_install_SOURCES): New variable. + * util/i386/pc/grub-install.in: Add a few condition checks to make it + usable on coreboot. + +2008-11-25 Felix Zielcke + + * util/grub-fstest.c (grub_term_get_current_input): Change return type + to `grub_term_input_t'. + (grub_term_get_current_output): Change return type to + `grub_term_output_t'. + +2008-11-22 Robert Millan + + Fix breakage on coreboot due to declaration mismatch. + * term/i386/pc/vga_text.c (grub_vga_text_init_fini): New function. + (grub_vga_text_term): Use grub_vga_text_init_fini() instead of + grub_vga_text_cls(). + + * kern/i386/loader.S (grub_multiboot_backward_relocator): Improve + comments. Avoid copying one more byte than necessary (just in case). + + * conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Change link address + to 0x200000 (avoids trouble with some OFW implementations, and matches + with the one in Yaboot). + Reported by Manoel Abranches + +2008-11-20 Robert Millan + + * kern/i386/coreboot/init.c (grub_time_tics): Remove variable. + (grub_get_rtc, grub_exit): Abort with grub_fatal() if called. + + * util/grub-mkconfig_lib.in (grub_warn): New function. + (convert_system_path_to_grub_path): Use grub_warn() when issuing + warnings, to obtain consistent formatting. + * util/grub.d/00_header.in: Likewise. + * util/update-grub_lib.in: Likewise. + + * loader/i386/linux.c (allocate_pages): Fix a warning. + Move comment text to `#error' stanza. + + Harmonize ieee1275's grub_available_iterate() with the generic + grub_machine_mmap_iterate() interface (fixes a recently-introduced + build problem on i386-ieee1275): + * kern/ieee1275/openfw.c (grub_available_iterate): Moved from here ... + * kern/ieee1275/mmap.c (grub_machine_mmap_iterate): ... here. Add third + parameter `type'. Update all users of this function. + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/ieee1275/mmap.c'. + * kern/ieee1275/init.c + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): Replace + with ... + (grub_machine_mmap_iterate): ... this. + * include/grub/i386/pc/memory.h (grub_machine_mmap_iterate): Change + return type to `grub_err_t'. Update all implementations of this + function prototype. + * include/grub/i386/coreboot/memory.h (grub_machine_mmap_iterate): + Likewise. + + Add `lsmmap' command (lists firmware-provided memory map): + * commands/lsmmap.c: New file. + * conf/i386-pc.rmk (pkglib_MODULES): Add `lsmmap.mod'. + (lsmmap_mod_SOURCES, lsmmap_mod_CFLAGS, lsmmap_mod_LDFLAGS): New + variables. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-11-19 Robert Millan + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Fix a typo. + * loader/i386/linux.c (grub_rescue_cmd_initrd): Implement a few needed + constraints to initrd allocation (based on code from + loader/i386/pc/linux.c). Without them, initrd was allocated too high + for Linux to find it. + +2008-11-14 Robert Millan + + * fs/cpio.c (grub_cpio_open): Compare `name' and `fn' by hand in + order to cope with duplicate slashes. + +2008-11-14 Robert Millan + + * include/grub/i386/coreboot/memory.h (GRUB_MEMORY_MACHINE_LOWER_SIZE): + Redefine to match with GRUB_MEMORY_MACHINE_UPPER_START (0x100000). We + don't want to mess with lower memory, because it is used in the Linux + loader. + + * loader/i386/linux.c (allocate_pages): Allocate `real_mode_mem' in + an appropriate place in lower memory, between 0x10000 and 0x90000, + like loader/i386/efi/linux.c does. Linux often panics if real_mode_mem + is in our heap (probably as a result of it being corrupted during + decompression). Add #error instance with comment to explain why this + loader isn't currently usable on PC/BIOS. + +2008-11-14 Robert Millan + + * term/i386/pc/serial.c [! GRUB_MACHINE_PCBIOS] + (GRUB_SERIAL_PORT_NUM): Fix miscalculation. + +2008-11-12 Robert Millan + + Make loader/i386/linux.c buildable on i386-pc (although disabled). + + * include/grub/i386/pc/init.h: Include `'. + (struct grub_machine_mmap_entry, grub_machine_mmap_iterate): Move + from here ... + * include/grub/i386/pc/memory.h: ... to here. + +2008-11-12 Robert Millan + + Fix build problems on i386-ieee1275 and *-efi (introduced by vga_text + split). + + * include/grub/i386/pc/console.h: Include `'. + (grub_console_cur_color, grub_console_real_putchar) + (grub_console_putchar, grub_console_getcharwidth, grub_console_getwh) + (grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): Move from here ... + * include/grub/i386/vga_common.h: ... to here (new file). + + * term/i386/pc/vga_text.c: Replace `' with + `' and `' with + `'. + * term/i386/vga_common.c: Replace `' with + `'. + +2008-11-12 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `term/i386/vga_common.c'. + * conf/i386.rmk (pkglib_MODULES): Add `vga_text.mod'. + (vga_text_mod_SOURCES, vga_text_mod_CFLAGS, vga_text_mod_LDFLAGS): New + variables. + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace + `term/i386/pc/console.c' with `term/i386/vga_common.c'. + + * kern/i386/coreboot/init.c (grub_machine_init): Replace call to + grub_console_init() with call to grub_vga_text_init(). + (grub_machine_fini): Replace call to + grub_console_fini() with call to grub_vga_text_fini() and + grub_at_keyboard_fini(). + + * include/grub/i386/pc/console.h: Include `'. + (grub_console_putchar, grub_console_getcharwidth, grub_console_getwh) + (grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): New function prototypes. + + * term/i386/pc/vga_text.c: Include `'. + (grub_vga_text_getxy, grub_vga_text_gotoxy, grub_vga_text_cls) + (grub_vga_text_setcursor): Static-ize. + (grub_vga_text_term): New structure. + (GRUB_MOD_INIT(vga_text), GRUB_MOD_FINI(vga_text)): New functions. + + * term/i386/pc/console.c: Remove `'. + (grub_console_cur_color, grub_console_standard_color) + (grub_console_normal_color, grub_console_highlight_color) + (map_char, grub_console_putchar, grub_console_getcharwidth) + (grub_console_getwh, grub_console_setcolorstate, grub_console_setcolor) + (grub_console_getcolor): Move from here ... + * term/i386/vga_common.c: ... to here (same function names). + +2008-11-12 Robert Millan + + Use newly-added Multiboot support in coreboot. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Replace + `kern/i386/coreboot/mmap.c' with `kern/i386/multiboot_mmap.c'. + + * kern/i386/coreboot/startup.S: Enable Multiboot header, fix its + alignment, set `MULTIBOOT_MEMORY_INFO' flag. + (codestart): Store the MBI in `startup_multiboot_info' when we're + being loaded using Multiboot. + + * kern/i386/coreboot/init.c (grub_machine_init): Move + grub_at_keyboard_init() call to beginning of function (useful for + debugging). Call grub_machine_mmap_init() before attempting to use + grub_machine_mmap_iterate(). + (grub_lower_mem, grub_upper_mem): Move from here ... + * kern/i386/multiboot_mmap.c (grub_lower_mem, grub_upper_mem): ... to + here (new file). + + * include/grub/i386/coreboot/memory.h (grub_machine_mmap_init): New + function prototype. + +2008-11-12 Robert Millan + + Fix a regression introduced by the at_keyboard.mod split. Because + some terminals are default on some platforms and non-default on + others, the first terminal being registered determines which is + going to be default. + + * kern/term.c (grub_term_register_input): If this is the first + terminal being registered, set it as the current one. + (grub_term_register_output): Likewise. + + * term/efi/console.c (grub_console_init): Do not call + grub_term_set_current_output() or grub_term_set_current_input(). + * term/ieee1275/ofconsole.c (grub_console_init): Likewise. + * term/i386/pc/console.c (grub_console_init): Likewise. + (grub_console_fini): Do not call grub_term_set_current_input() + (but leave grub_term_set_current_output() to restore text mode). + +2008-11-10 Robert Millan + + * util/grub.d/00_header.in: Add backward compatibility check for + versions of terminal.mod that don't understand `terminal_input' or + `terminal_output'. + +2008-11-09 Robert Millan + + * commands/terminal.c (GRUB_MOD_FINI(terminal)): Unregister + `terminal_input' / `terminal_output', not `terminal'. + +2008-11-08 Robert Millan + + * Makefile.in (include_DATA): Fix srcdir=. assumption. + (DISTCLEANFILES): Add `build_env.mk'. + +2008-11-08 Robert Millan + + * term/i386/pc/vesafb.c (grub_vesafb_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * util/console.c (grub_ncurses_term): Split in ... + (grub_ncurses_term_input): ... this, and ... + (grub_ncurses_term_output): ... this. Update all users. + * term/ieee1275/ofconsole.c: Remove stale `#endif'. + +2008-11-08 Robert Millan + + * Makefile.in (PKGLIB): Add $(pkglib_BUILDDIR). + (PKGDATA): Add $(pkgdata_SRCDIR). + (pkglib_BUILDDIR): New variable. + (pkgdata_SRCDIR): New variable. + (build_env.mk): New target. + (include_DATA): New variable. + (install-local): Install $(include_DATA) files in $(includedir). + +2008-11-07 Pavel Roskin + + * gendistlist.sh: Use C locale for sorting to ensure consistent + output on all systems. + + * util/grub.d/00_header.in: Remove incorrect space before + "serial". + +2008-11-07 Robert Millan + + * include/multiboot2.h (struct multiboot_header): Add `flags' member as + per specification. + * loader/multiboot2.c (grub_multiboot2): Fix Multiboot2 header check. + * loader/multiboot_loader.c (find_multi_boot2_header): New function + (based on find_multi_boot1_header). + (grub_rescue_cmd_multiboot_loader): Check for Multiboot2 header, + using find_multi_boot2_header(), and abort if neither Multiboot or + Multiboot headers were found. + +2008-11-07 Robert Millan + + Modularize at_keyboard.mod: + + * conf/i386.rmk (pkglib_MODULES): Add `at_keyboard.mod'. + (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) + (at_keyboard_mod_LDFLAGS): New variables. + + Actual terminal split: + + * include/grub/term.h (struct grub_term): Split in ... + (struct grub_term_input): ... this, and ... + (struct grub_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/term.c (grub_term_list): Split in ... + (grub_term_list_input): ... this, and ... + (grub_term_list_output): ... this. Update all users. + (grub_cur_term): Split in ... + (grub_cur_term_input): ... this, and ... + (grub_cur_term_output): ... this. Update all users. + (grub_term_set_current): Split in ... + (grub_term_set_current_input): ... this, and ... + (grub_term_set_current_output): ... this. + (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + (grub_term_register): Split in ... + (grub_term_register_input): ... this, and ... + (grub_term_register_output): ... this. + (grub_term_unregister): Split in ... + (grub_term_unregister_input): ... this, and ... + (grub_term_unregister_output): ... this. + (grub_term_iterate): Split in ... + (grub_term_iterate_input): ... this, and ... + (grub_term_iterate_output): ... this. + + * kern/misc.c (grub_abort): Split use of grub_term_get_current() into + a check for input and one for output (and only attempt to get keys + from user when input works). + + * util/grub-probe.c (grub_term_get_current): Split in ... + (grub_term_get_current_input): ... this, and ... + (grub_term_get_current_output): ... this. + * util/grub-fstest.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/grub-editenv.c: Likewise. + + Portability adjustments: + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Remove + `term/i386/pc/at_keyboard.c'. + * kern/ieee1275/init.c [__i386__] (grub_machine_init): Remove call to + grub_keyboard_controller_init() (now handled by terminal .init). + * kern/i386/coreboot/init.c (grub_machine_init): Add call to + grub_at_keyboard_init(). + * include/grub/i386/ieee1275/console.h (grub_keyboard_controller_init) + (grub_console_checkkey, grub_console_getkey): Remove (now provided by + at_keyboard.mod via input terminal interface). + * include/grub/i386/coreboot/console.h: Convert into a stub for + `'. + + Migrate full terminals to new API: + + * term/efi/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + * term/ieee1275/ofconsole.c: Remove __i386__ hack. + (grub_ofconsole_init): Split into ... + (grub_ofconsole_init_input): ... this, and ... + (grub_ofconsole_init_output): ... this. + (grub_ofconsole_term): Split into ... + (grub_ofconsole_term_input): ... this, and ... + (grub_ofconsole_term_output): ... this. Update all users. + * term/i386/pc/serial.c (grub_serial_term): Split into ... + (grub_serial_term_input): ... this, and ... + (grub_serial_term_output): ... this. Update all users. + * term/i386/pc/console.c (grub_console_term): Split into ... + (grub_console_term_input): ... this, and ... + (grub_console_term_output): ... this. Update all users. + (grub_console_term_input): Only enable it on PC/BIOS platform. + (grub_console_init): Remove grub_keyboard_controller_init() call. + + Migrate input terminals to new API: + + * term/i386/pc/at_keyboard.c: Replace `cpu' and `machine' with + `i386' and `i386/pc' to enable build on x86_64 (this driver is + i386-specific anyway). + (grub_console_checkkey): Rename to ... + (grub_at_keyboard_checkkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_orig): New variable. + (grub_console_getkey): Rename to ... + (grub_at_keyboard_getkey): ... this. Static-ize. Update all + users. + (grub_keyboard_controller_init): Static-ize. Save original + controller value so that it can be restored ... + (grub_keyboard_controller_fini): ... here (new function). + (grub_at_keyboard_term): New structure. + (GRUB_MOD_INIT(at_keyboard), GRUB_MOD_FINI(at_keyboard)): New + functions. + + Migrate output terminals to new API: + + * term/i386/pc/vga.c (grub_vga_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * term/gfxterm.c (grub_video_term): Change type to + `struct grub_term_output'. Remove `.checkkey' and `.getkey' + members. Update all users. + * include/grub/i386/pc/console.h (grub_console_checkkey) + (grub_console_getkey): Do not export (no longer needed by gfxterm, + etc). + + Migrate `terminal' command and userland tools to new API: + + * commands/terminal.c (grub_cmd_terminal): Split into ... + (grub_cmd_terminal_input): ... this, and ... + (grub_cmd_terminal_output): ... this. + (GRUB_MOD_INIT(terminal)): Split `terminal' command in two commands: + `terminal_input' and `terminal_output'. + * util/grub.d/00_header.in: Adjust `terminal' calls to new + `terminal_input' / `terminal_output' API. + * util/grub-mkconfig.in: Export ${GRUB_TERMINAL_INPUT} and + ${GRUB_TERMINAL_OUTPUT} instead of ${GRUB_TERMINAL} (and if user + provided ${GRUB_TERMINAL}, convert it). + +2008-11-04 Robert Millan + + * util/grub.d/10_freebsd.in: New file. Generate grub configuration + for FreeBSD. + * conf/common.rmk (grub-mkconfig_SCRIPTS): Add 10_freebsd. + +2008-11-03 Bean + + * kern/elf.c (grub_elf32_load): Revert to previous code. + (grub_elf64_load): Likewise. + + * loader/i386/bsd.c (grub_bsd_elf32_hook): Change return address. + +2008-11-01 Robert Millan + + * Makefile.in (CPPFLAGS): Fix builddir=. assumption. + (TARGET_CPPFLAGS): Likewise. + * genmk.rb (mod_src): Fix builddir=. and srcdir=. assumptions. + +2008-11-01 Carles Pina i Estany + + * normal/menu.c (run_menu): Add Previous and Next Page keys in menu. + +2008-10-29 Guillem Jover + + * disk/lvm.c (grub_lvm_scan_device): Fix error recovery by delaying the + addition of objects until the code is not going to be able to fail. + +2008-10-29 Guillem Jover + + * disk/lvm.c (grub_lvm_scan_device): Fix possible NULL value handling + (add a missing NULL check, and correct them by moving the pointer + operations after the actual check). + +2008-10-29 Robert Millan + + * util/i386/pc/grub-install.in: Handle empty string as output from + make_system_path_relative_to_its_root(). + +2008-10-05 Hans Lambermont + + * disk/lvm.c (grub_lvm_scan_device): Allocate buffer space for the + circular metadata worst case scenario. If the metadata is circular + then copy the wrap in place. + * include/grub/lvm.h: Add GRUB_LVM_MDA_HEADER_SIZE, from the LVM2 + project lib/format_text/layout.h + Circular metadata bug found and patch debugged by Jan Derk Gerlings. + +2008-10-03 Felix Zielcke + + * util/i386/pc/grub-install.in: Source grub-mkconfig_lib instead of update-grub_lib. + +2008-10-03 Felix Zielcke + + * util/update-grub_lib.in: Mention filename in warning message. + +2008-09-29 Felix Zielcke + + * NEWS: Update for rename of update-grub to grub-mkconfig. + +2008-09-29 Felix Zielcke + + * util/update-grub_lib.in: Copy to ... + * util/grub-mkconfig_lib.in: ... this. Update all users. + * util/update-grub_lib.in: Make it a stub to `grub-mkconfig_lib.in'. + * util/update-grub.in: Rename to ... + * util/grub-mkconfig.in: ... this. Update all users. Remove `-y' + option. Add `--output' option to allow users to specify the generated + configuration file. Default to stdout. + (update_grub_dir): Rename to ... + (grub_mkconfig_dir): ... this. + (grub_cfg): Default to an empty string. + * conf/common.rmk (update-grub): Rename to ... + (grub-mkconfig): ... this. + (update-grub_lib): Copy to ... + (grub-mkconfig_lib): ... this. + (update-grub_SCRIPTS): Copy to ... + (grub-mkconfig_SCRIPTS): ... this. Update all users. + (update-grub_DATA): Rename to ... + (grub-mkconfig_DATA): ... this. + +2008-09-28 Robert Millan + + * fs/iso9660.c (struct grub_iso9660_primary_voldesc): Rename `created' + to `modified'. Add the real `created' field. + (grub_iso9660_uuid): Use `modified' rather than `created' for + constructing the UUID. + +2008-09-28 Felix Zielcke + + fs/jfs.c (grub_jfs_find_file): Treat multiple slashes like one. + Based on code from Tomas Ebenlendr . + +2008-09-28 Bean + + * fs/ntfs.c (grub_ntfs_iterate_dir): Fix a bug in the previous patch. + Thanks to Christian Franke for finding this bug. + +2008-09-25 Robert Millan + + * util/grub-mkdevicemap.c (make_device_map): Actually replace all + instances of grub_util_get_disk_name() (see previous commit). + +2008-09-25 Robert Millan + + * conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Remove + `util/i386/get_disk_name.c'. + * conf/i386-efi.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Remove + `util/ieee1275/get_disk_name.c'. + * include/grub/util/misc.h (grub_util_get_disk_name): Remove. + * util/ieee1275/get_disk_name.c: Remove file. + * util/i386/get_disk_name.c: Remove file. + * util/grub-mkdevicemap.c (make_device_map): Back to hardcoding + "hd%d" for device.map entries, rather than using + grub_util_get_disk_name(). + +2008-09-24 Carles Pina i Estany + + * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Fix `unused parameter' + warning. + * commands/i386/pc/pxecmd.c (dmraid_nvidia): Likewise. + +2008-09-24 Carles Pina i Estany + + * include/grub/i386/pc/console.h (GRUB_TERM_NPAGE): + Changed to 0x5100. + (GRUB_TERM_PPAGE): Changed to 0x4900. + +2008-09-24 Robert Millan + + * include/grub/powerpc/ieee1275/console.h (GRUB_CONSOLE_KEY_*): Remove + macros (they were i386-pc specific). + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/efi/console.h: Likewise. + +2008-09-22 Bean + + * fs/ntfs.c (grub_ntfs_iterate_dir): Fix a rare case where $BITMAP is + resident and in attribute list. + + * include/grub/ntfs.h (BMP_LEN): Removed. + +2008-09-22 Bean + + * disk/ata.c (grub_atapi_open): Initialize devfnd, no need to set + scsi->name and scsi->luns, as they will be set in grub_scsi_open. + + * disk/scsi.c (grub_scsi_open): Don't call p->close (scsi) here when + error occurs, as grub_disk_open will call grub_disk_close, which will + call p->close (scsi). + +2008-09-21 Felix Zielcke + + * configure.ac (AC_INIT): Quote `GRUB' string and version number. + (AC_PREREQ): Bumped to 2.59. + (AC_TRY_COMPILE): Replace obsolete macro with ... + (AC_COMPILE_IFELSE): ... this. + * aclocal.m4 (AC_TRY_LINK): Replace obsolete macro with ... + (AC_LINK_IFELSE): ... this. + +2008-09-21 Felix Zielcke + + * autogen.sh: Add a call to `gendistlist.sh'. + +2008-09-19 Christian Franke + + * aclocal.m4 (grub_CHECK_ENABLE_EXECUTE_STACK): New function. + * configure.ac: Call grub_CHECK_ENABLE_EXECUTE_STACK. + * include/grub/misc.h [NEED_ENABLE_EXECUTE_STACK]: + Export __enable_execute_stack() to modules. + * kern/misc.c [NEED_ENABLE_EXECUTE_STACK] (__enable_execute_stack): + New function. + +2008-09-09 Felix Zielcke + + * Makefile.in (RMKFILES): Add `i386.rmk' and `x86_64-efi.rmk'. + Sort the list. + +2008-09-09 Felix Zielcke + + * util/hostdisk.c: Replace #include with + #include . + +2008-09-08 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Skip + segments when their filesz is zero (grub_file_read() interprets + zero-size as "read until EOF", which results in memory corruption). + Use `lowest_segment' rather than 0 for calculating the current + segment load address. + +2008-09-08 Robert Millan + + * util/hostdisk.c (open_device): Replace a grub_util_info() call + with grub_dprintf("hostdisk", ...), as it was so verbose that it + clobbered useful information. + +2008-09-08 Robert Millan + + * include/grub/util/biosdisk.h: Move to ... + * include/grub/util/hostdisk.h: ... here. Update all users. + * util/biosdisk.c: Move to ... + * util/hostdisk.c: ... here. Update all users. + +2008-09-07 Robert Millan + + * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): Remove + variables. + (grub_multiboot): Move `mbi' allocation upwards, so that mmap address + and length can be stored directly in the `mbi->mmap_addr' and + `mbi->mmap_length' struct fields. + +2008-09-07 Robert Millan + + * conf/i386.rmk: New file. Provides declaration for building + `cpuid.mod'. + * conf/i386-pc.rmk (pkglib_MODULES): Remove `cpuid.mod'. + (cpuid_mod_SOURCES, cpuid_mod_CFLAGS, cpuid_mod_LDFLAGS): Remove + variables. + Include `conf/i386.mk'. + * conf/i386-efi.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-09-07 Vesa Jääskeläinen + + Based on patch created by Colin D Bennett . + Adds optimization support for BGR based modes. + + * include/grub/i386/pc/vbeblit.h (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8) Removed. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_replace_directN): Added. + (grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGB888): Likewise. + (grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise. + + * include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8) Removed. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill_direct32): Added. + (grub_video_i386_vbefill_direct24): Likewise. + (grub_video_i386_vbefill_direct16): Likewise. + (grub_video_i386_vbefill_direct8): Likewise. + + * include/grub/video.h (grub_video_blit_format): Removed + GRUB_VIDEO_BLIT_FORMAT_R8G8B8A8, GRUB_VIDEO_BLIT_FORMAT_R8G8B8. + (grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_RGBA_8888, + GRUB_VIDEO_BLIT_FORMAT_BGRA_8888, GRUB_VIDEO_BLIT_FORMAT_RGB_888, + GRUB_VIDEO_BLIT_FORMAT_BGR_888, GRUB_VIDEO_BLIT_FORMAT_RGB_565, + GRUB_VIDEO_BLIT_FORMAT_BGR_565. + + * video/video.c (grub_video_get_blit_format): Updated to use new + blit formats. Added handling for 16 bit color modes. + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Updated to use new + fillers. + (common_blitter): Updated to use new blitters. + + * video/i386/pc/vbeblit.c (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): + Removed. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_replace_directN): Added. + (grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGRX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_BGR888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGBX8888_RGB888): Likewise. + (grub_video_i386_vbeblit_replace_RGB888_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGBX8888): Likewise. + (grub_video_i386_vbeblit_replace_index_RGB888): Likewise. + (grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_BGR888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_RGB888_RGBA8888): Likewise. + (grub_video_i386_vbeblit_blend_index_RGBA8888): Likewise. + + * video/i386/pc/vbefill.c (grub_video_i386_vbefill_R8G8B8A8): Removed. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill_direct32): Added. + (grub_video_i386_vbefill_direct24): Likewise. + (grub_video_i386_vbefill_direct16): Likewise. + (grub_video_i386_vbefill_direct8): Likewise. + + * video/readers/jpeg.c (grub_jpeg_decode_sos): Adapt to new blitter + types. + + * video/readers/tga.c (grub_video_reader_tga): Adapt to new blitter + types. + + * video/readers/png.c (grub_png_decode_image_header): Adapt to new + blitter types. + + * video/bitmap.c (grub_video_bitmap_create): Adapt to new blitter + types. + +2008-09-06 Felix Zielcke + + * disk/raid.c (insert_array): Set `array->chunk_size' to 64 for + RAID level 1. + +2008-09-06 Felix Zielcke + + * fs/iso9660.c (grub_iso9660_date): New structure. + (grub_iso9660_primary_voldesc): Add `grub_iso9660_date' member. + (grub_iso9660_uuid): New function. + +2008-09-05 Bean + + * fs/fshelp.c (grub_fshelp_find_file): Handle case insensitive names. + + * fs/ntfs.c (list_file): Ignore names in DOS namespace, set the case + insensitive bit for names in Win32 and Win32 & DOS namespace. + + * include/grub/fshelp.h (GRUB_FSHELP_CASE_INSENSITIVE): New macro. + + * include/grub/types.h (LONG_MAX): Likewise. + +2008-09-04 Felix Zielcke + + * util/getroot.c: Include . + (grub_util_get_grub_dev): Rewrite to use asprintf for mdraid devices, + add support for /dev/md/N devices and handle LVM double dash escaping. + +2008-09-04 Felix Zielcke + + * config.guess: Update to latest version from config git. + * config.sub: Likewise. + +2008-09-03 Robert Millan + + * disk/scsi.c (grub_scsi_open): Remove size limit when printing + `disk->total_sectors'. + +2008-09-01 Colin D Bennett + + * include/grub/normal.h: Fixed incorrect comment for + GRUB_COMMAND_FLAG_NO_ARG_PARSE. + +2008-09-01 Colin D Bennett + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Replaced constant + values with defines. + + * include/grub/i386/pc/vbe.h (GRUB_VBE_MODEATTR_SUPPORTED): Added. + (GRUB_VBE_MODEATTR_RESERVED_1): Likewise. + (GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT): Likewise. + (GRUB_VBE_MODEATTR_COLOR): Likewise. + (GRUB_VBE_MODEATTR_GRAPHICS): Likewise. + (GRUB_VBE_MODEATTR_VGA_COMPATIBLE): Likewise. + (GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_LFB_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_INTERLACED_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_STEREO_AVAIL): Likewise. + (GRUB_VBE_MODEATTR_DUAL_DISPLAY_START): Likewise. + (GRUB_VBE_MEMORY_MODEL_TEXT): Likewise. + (GRUB_VBE_MEMORY_MODEL_CGA): Likewise. + (GRUB_VBE_MEMORY_MODEL_HERCULES): Likewise. + (GRUB_VBE_MEMORY_MODEL_PLANAR): Likewise. + (GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256): Likewise. + (GRUB_VBE_MEMORY_MODEL_YUV): Likewise. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c (grub_get_multiboot_mmap_len): Fix + declaration. + (grub_multiboot): Fix a few warnings. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c: Update comment not to say that + boot_device support is unimplemented. + +2008-08-31 Robert Millan + + * loader/i386/pc/multiboot.c: Update comment not to say that a.out + or memory map support are unimplemented. + +2008-08-31 Colin D Bennett + + * util/i386/pc/grub-mkrescue.in: Support multiple overlay directories. + +2008-08-31 Colin D Bennett + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbeinfo): Show VBE version and + total video memory in 'vbeinfo' output; show color format details for + each video mode. + +2008-08-30 Pavel Roskin + + * util/genmoddep.c: Remove for real this time. + * DISTLIST: Remove util/genmoddep.c. + +2008-08-30 Robert Millan + + * kern/i386/pc/startup.S (multiboot_header): Force 4-byte alignment + as required by Multiboot spec (it was already 4-byte aligned, but + only by chance). + +2008-08-29 Pavel Roskin + + * kern/powerpc/ieee1275/crt0.S: Rename to ... + * kern/powerpc/ieee1275/startup.S: ... this. + * conf/powerpc-ieee1275.rmk: Adjust for the above. + * DISTLIST: Likewise. + + * kern/powerpc/ieee1275/crt0.S: Include grub/symbol.h and + grub/cpu/kernel.h. Add start label for consistency with other + platforms. Add grub_prefix immediately after start. Add jump + to the code after grub_prefix. + * include/grub/powerpc/kernel.h: Provide valid values for + GRUB_KERNEL_CPU_PREFIX and GRUB_KERNEL_CPU_DATA_END. + +2008-08-29 Bean + + * configure.ac: Change host_os to cygwin for mingw. + (asprintf): New check for function. + + * include/grub/symbol.h: Replace #ifndef __CYGWIN__ with + #if ! defined (__CYGWIN__) && ! defined (__MINGW32__). + + * include/grub/util/misc.h: #include and , + declare asprintf if HAVE_ASPRINTF is not set, declare fseeko, ftello, + sync, sleep and grub_util_get_disk_size for mingw. + + * util/biosdisk.c (grub_util_biosdisk_open): Use grub_util_get_disk_size + to get size in mingw. + (open_device): Use flag O_BINARY if it's defined. + (find_root_device): Add dummy code for mingw. + + * util/grub-mkdevicemap.c (get_floppy_disk_name): Return 0 for mingw. + (get_ide_disk_name): Return //./PHYSICALDRIVE%d for mingw. + (get_scsi_disk_name): Return 0 for mingw. + + * util/hostfs.c: #include . + (grub_hostfs_open): Use "rb" flag to open file, use + grub_util_get_disk_size to get disk size for mingw. + + * util/misc.c: #include and in mingw. + (asprintf): New function if HAVE_ASPRINTF is not set. + (sync): New function for mingw. + (sleep): Likewise. + (grub_util_get_disk_size): Likewise. + +2008-08-28 Pavel Roskin + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + kern/time.c. + +2008-08-28 Robert Millan + + * util/biosdisk.c (find_grub_drive): Declare missing `i' variable. + +2008-08-28 Robert Millan + + Change find_grub_drive() syntax so it doesn't prevent it from + detecting NULL names as errors. + + * util/biosdisk.c (find_grub_drive): Move free slot search code + from here ... + (find_free_slot): ... to here. + (read_device_map): Use find_free_slot() to search for free slots. + +2008-08-27 Marco Gerards + + * conf/common.rmk (pkglib_MODULES): Add scsi.mod. + (scsi_mod_SOURCES): New variable. + (scsi_mod_CFLAGS): Likewise + (scsi_mod_LDFLAGS): Likewise. + + * disk/scsi.c: New file. + + * include/grub/scsi.h: Likewise. + + * include/grub/scsicmd.h: Likewise. + + * disk/ata.c: Include . + (grub_atapi_packet): Do not use grub_ata_cmd, use registers + instead. + (grub_ata_iterate): Skip ATAPI devices. + (grub_ata_open): Only handle ATAPI devices. + (struct grub_atapi_read): Removed. + (grub_atapi_readsector): Likewise. + (grub_ata_read): No longer handle ATAPI devices. + (grub_ata_write): Likewise. + (grub_atapi_iterate): New function. + (grub_atapi_read): Likewise. + (grub_atapi_write): Likewise. + (grub_atapi_open): Likewise. + (grub_atapi_close): Likewise. + (grub_atapi_dev): New variable. + (GRUB_MOD_INIT(ata)): Register ATAPI as SCSI device. + (GRUB_MOD_FINI(ata)): Unregister ATAPI. + + * include/grub/disk.h (enum grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_SCSI_ID'. + +2008-08-26 Robert Millan + + * util/biosdisk.c (grub_util_biosdisk_open, open_device) + (grub_util_biosdisk_get_grub_dev): Make error messages a bit more + descriptive. + +2008-08-23 Bean + + * conf/common.rmk (grub_probe_SOURCES): Add disk/mdraid_linux.c. + (grub_fstest_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, + disk/mdraid_linux.c and disk/dmraid_nvidia.c and lib/crc.c. + (pkglib_MODULES): Add raid5rec.mod, raid6rec.mod, mdraid.mod and + dm_nv.mod. + (raid5rec_mod_SOURCES): New macro. + (raid5rec_mod_CFLAGS): Likewise. + (raid5rec_mod_LDFLAGS): Likewise. + (raid6rec_mod_SOURCES): Likewise. + (raid6rec_mod_CFLAGS): Likewise. + (raid6rec_mod_LDFLAGS): Likewise. + (mdraid_mod_SOURCES): Likewise. + (mdraid_mod_CFLAGS): Likewise. + (mdraid_mod_LDFLAGS): Likewise. + (dm_nv_mod_SOURCES): Likewise. + (dm_nv_mod_CFLAGS): Likewise. + (dm_nv_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add disk/mdraid_linux.c. + (grub_emu_SOURCES): Add disk/raid5_recover.c, disk/raid6_recover.c, + disk/mdraid_linux.c and disk/dmraid_nvidia.c. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add disk/raid5_recover.c, + disk/raid6_recover.c, disk/mdraid_linux.c and disk/dmraid_nvidia.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * disk/raid5_recover.c: New file. + + * disk/raid6_recover.c: Likewise. + + * disk/mdraid_linux.c: Likewise. + + * disk/dmraid_nvidia.c: Likewise. + + * disk/i386/pc/biosdisk.c: Set total_sectors of cdrom device to + ULONG_MAX. + + * disk/raid.c (grub_raid_open): Use the size of the smallest disk to + calculate the size of raid device. + (grub_raid_read): Simplify raid0 code. Support raid4, raid6 and four + different layout of raid5. + (grub_raid_scan_device): Remove code specific to mdraid. + (grub_raid_list): New variable. + (free_array): New function. + (grub_raid_register): Likewise. + (grub_raid_unregister): Likewise. + (grub_raid_rescan): Likewise. + (GRUB_MOD_INIT): Don't iterate device here. + (GRUB_MOD_FINI): Use free_array to release resource. + + * include/grub/raid.h: Remove macro and structure specific to mdraid. + (grub_raid5_recover_func_t): New function variable type. + (grub_raid6_recover_func_t): Likewise. + (grub_raid5_recover_func): New variable. + (grub_raid6_recover_func): Likewise. + (grub_raid_register): New function. + (grub_raid_unregister): Likewise. + (grub_raid_rescan): Likewise. + (grub_raid_block_xor): Likewise. + + * util/grub-fstest.c: Add #include and . + (CMD_CRC): New macro. + (part): Removed. + (read_file): Handle device as well as file. + (cmd_crc): New function. + (fstest): Handle multiple disks. + (options): Remove part, raw and long, add root and diskcount. + (usage): Add crc, remove -p, -r, -l, add -r and -c. + (main): Find the first non option entry and ignore subsequent options, + add handling for the new options, support multiple disks. + + * util/grub-probe.c (probe): Add mdraid to abstraction_name. + +2008-08-23 Bean + + * normal/x86_64/setjmp.S (grub_longjmp): Return 1 when val = 0. + + * genfslist.sh: Ignore kernel.mod. + + * genpartmaplist.sh: Likewise. + +2008-08-23 Robert Millan + + * util/getroot.c (find_root_device): Skip anything that starts with + a dot, not just directories. This avoids things like /dev/.tmp.md0. + +2008-08-22 Felix Zielcke + + * util/update-grub.in (GRUB_GFXMODE): Export variable. + * util/grub.d/00_header.in: Allow the administrator to change default + gfxmode via ${GRUB_GFXMODE}. + +2008-08-21 Felix Zielcke + + * fs/ntfs.c (grub_ntfs_mount): Fix a memory leak. + +2008-08-21 Robert Millan + + * loader/i386/linux.c: New file. Implements generic 32-bit Linux + loader. + * conf/i386-coreboot.rmk (_linux_mod_SOURCES): Replace + `loader/i386/pc/linux.c' with `loader/i386/linux.c'. + +2008-08-20 Carles Pina i Estany + + * menu/normal.c (run_menu): Replace hardcoded numbers with macros + (16 for GRUB_TERM_UP and 14 for GRUB_TERM_DOWN) + +2008-08-19 Robert Millan + + * term/gfxterm.c (DEFAULT_CURSOR_COLOR): Remove. + (struct grub_virtual_screen): Remove `cursor_color'. + (grub_virtual_screen_setup): Remove `virtual_screen.cursor_color' + initialization. + (write_cursor): Use `virtual_screen.fg_color' to draw cursor. + +2008-08-18 Robert Millan + + Unify (identical) linux_normal.c files. + * loader/i386/efi/linux_normal.c: Move from here ... + * loader/linux_normal.c: ... to here. Update all users. + * loader/i386/pc/linux_normal.c: Delete. Update all users. + * loader/i386/ieee1275/linux_normal.c: Likewise. + +2008-08-18 Robert Millan + + * include/grub/i386/linux.h (LINUX_LOADER_ID_LILO) + (LINUX_LOADER_ID_LOADLIN, LINUX_LOADER_ID_BOOTSECT) + (LINUX_LOADER_ID_SYSLINUX, LINUX_LOADER_ID_ETHERBOOT) + (LINUX_LOADER_ID_ELILO, LINUX_LOADER_ID_GRUB, LINUX_LOADER_ID_UBOOT) + (LINUX_LOADER_ID_XEN, LINUX_LOADER_ID_GUJIN, LINUX_LOADER_ID_QEMU): + New macros. + (GRUB_LINUX_CL_OFFSET, GRUB_LINUX_CL_END_OFFSET): Move from here ... + * loader/i386/pc/linux.c (GRUB_LINUX_CL_OFFSET) + (GRUB_LINUX_CL_END_OFFSET): ... to here. + * loader/i386/efi/linux.c (GRUB_EFI_CL_OFFSET): Rename to ... + (GRUB_LINUX_CL_OFFSET): ... this. Update all users. + (GRUB_EFI_CL_END_OFFSET): Rename to ... + (GRUB_LINUX_CL_END_OFFSET): ... this. Update all users. + (grub_rescue_cmd_linux): Macroify `type_of_loader' initialization. + Initialize `params->video_cursor_x' and `params->video_cursor_y' + portably using grub_getxy(). + Replace `-EFI' with `-bzImage' in boot message. + +2008-08-17 Robert Millan + + * include/grub/x86_64/kernel.h: New file ( stub). + +2008-08-17 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'. + + * include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE) + (GRUB_MACHINE_MEMORY_RESERVED): New macros. + (grub_machine_mmap_iterate): New function declaration. + * include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New + structure. + (GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New + macros. + + * kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region + type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'. + Move e820 parsing from here ... + * kern/i386/pc/mmap.c: New file. + (grub_machine_mmap_iterate): ... to here. + + * include/grub/i386/coreboot/memory.h: Remove `'. + (GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ... + (GRUB_MACHINE_MEMORY_AVAILABLE): ... this. Update all users. + (grub_available_iterate): Redeclare to return `void', and redeclare + its hook to use grub_uint64_t as addr and size parameters, and rename + to ... + (grub_machine_mmap_iterate): ... this. Update all users. + + * kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop + to make it more readable. Rename to ... + (grub_machine_mmap_iterate): ... this. + + * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables. + (grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions. + (grub_multiboot): Allocate an extra region after the payload, and fill + it with a Multiboot memory map. Adjust a.out loader to calculate size + with the extra space. + (grub_multiboot_load_elf32): Adjust elf32 loader to calculate size + with the extra space. + +2008-08-17 Carles Pina i Estany + + * menu/normal.c (run_menu): Add Home and End keys in grub-menu. + +2008-08-17 Felix Zielcke + + * gendistlist.sh: Add *.y, *.tex, *.texi, grub.cfg, README, *.sc, + mdate-sh to the list `find' searches for. + * DISTLIST: Regenerated. + +2008-08-16 Felix Zielcke + + * gendistlist.sh (EXTRA_DISTFILES): Remove gensymlist.sh, + genkernsyms.sh. Add geninit.sh, geninitheader.sh, genkernsyms.sh.in, + genmoddep.awk, gensymlist.sh.in. + (DISTDIRS): Add bus, docs, hook, lib. + * DISTLIST: Regenerated. + * NEWS: Add cygwin support and change the `os-prober' entry a bit. + +2008-08-16 Robert Millan + + * disk/raid.c (grub_raid_init): Handle/report errors set by + grub_device_iterate(). + * disk/lvm.c (grub_lvm_init): Likewise. + +2008-08-15 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/i386-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * conf/x86_64-efi.rmk (pkglib_MODULES): Add datetime.mod, date.mod + and datehook.mod. + (datetime_mod_SOURCES): New macro. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + + * kern/env.c (grub_env_insert): Fix a bug in prevp pointer. + + * commands/date.c: New file. + + * hook/datehook.c: Likewise. + + * include/grub/lib/datetime.h: Likewise. + + * include/grub/i386/cmos.h: Likewise. + + * lib/datetime.c: Likewise. + + * lib/i386/datetime.c: Likewise. + + * lib/efi/datetime.c: Likewise. + +2008-08-14 Robert Millan + + * conf/common.rmk (bin_UTILITIES): Add `grub-mkelfimage'. + (grub_mkelfimage_SOURCES): New variable. + (util/elf/grub-mkimage.c_DEPENDENCIES): Likewise. + + * conf/i386-coreboot.rmk (bin_UTILITIES, grub_mkimage_SOURCES) + (grub_mkimage_LDFLAGS, util/elf/grub-mkimage.c_DEPENDENCIES): Remove. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + + * kern/ieee1275/init.c: Include `'. + * kern/i386/coreboot/init.c: Likewise. + + * kern/i386/ieee1275/startup.S: Replace `' + with `'. + (GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Renamed + to ... + (GRUB_KERNEL_CPU_PREFIX, GRUB_KERNEL_CPU_DATA_END): ... this. + * kern/i386/coreboot/startup.S: Likewise. + + * include/grub/powerpc/ieee1275/kernel.h (GRUB_MOD_ALIGN) + (GRUB_MOD_GAP): Remove. + * include/grub/powerpc/kernel.h: New file. + * include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX) + (GRUB_KERNEL_MACHINE_DATA_END): Remove. + * include/grub/i386/kernel.h: New file. + * include/grub/i386/coreboot/kernel.h (GRUB_MOD_ALIGN) + (GRUB_MOD_GAP, GRUB_KERNEL_MACHINE_PREFIX) + (GRUB_KERNEL_MACHINE_DATA_END): Remove. + + * util/ieee1275/grub-install.in (grub_mkimage): Initialize to use + `grub-mkelfimage'. + Use --directory when invoking grub_mkimage. + + * util/elf/grub-mkimage.c: Include `'. + (add_segments): Replace GRUB_KERNEL_MACHINE_DATA_END and + GRUB_KERNEL_MACHINE_PREFIX with GRUB_KERNEL_CPU_DATA_END + and GRUB_KERNEL_CPU_PREFIX. + +2008-08-14 Felix Zielcke + + * include/grub/err.h (grub_err_printf): New function prototype. + * util/misc.c (grub_err_printf): New function. + * kern/misc.c [! GRUB_UTIL] (grub_err_printf): New alias for + grub_printf. + * kern/err.c (grub_print_error): Use grub_err_printf. + +2008-08-13 Robert Millan + + * docs/grub.cfg: Remove `/dev/' prefix in GNU/Hurd boot entry. + +2008-08-13 Robert Millan + + * docs/grub.cfg: Use the native device name for the example GNU/Hurd + boot entry. + +2008-08-12 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Move part + of the relocation code from here ... + (grub_multiboot): ... to here. + (forward_relocator, backward_relocator): Move from here ... + * kern/i386/loader.S (grub_multiboot_forward_relocator) + (grub_multiboot_backward_relocator): ... to here. + (grub_multiboot_real_boot): Use %edx for entry offset. Put Multiboot + magic in %eax. Use %ebp for jumping (so %edx is not trashed). + * include/grub/i386/loader.h (grub_multiboot_forward_relocator) + (grub_multiboot_forward_relocator_end) + (grub_multiboot_backward_relocator) + (grub_multiboot_backward_relocator_end): New variables. + +2008-08-12 Bean + + * disk/raid.c (grub_raid_read): Fix a bug in raid0 code. + +2008-08-11 Robert Millan + + * kern/i386/linuxbios/startup.S: Move from here ... + * kern/i386/coreboot/startup.S: ... to here. + + * kern/i386/linuxbios/init.c: Move from here ... + * kern/i386/coreboot/init.c: ... to here. + + * kern/i386/linuxbios/table.c: Move from here ... + * kern/i386/coreboot/mmap.c: ... to here. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Update moved files. + +2008-08-11 Robert Millan + + * kern/device.c (grub_device_open): Do not handle grub_disk_open() + errors. Leave it to the upper layer to handle them. + +2008-08-09 Christian Franke + + * Makefile.in: Add `target_os' and `enable_grub_pe2elf'. + * conf/common.rmk: Install `grub-pe2elf' only if requested. + Install `grub.d/10_windows' only on Cygwin. + * configure.ac: Add subst of `target_os'. + Check `target_os' also before setting TARGET_OBJ2ELF. + Add `--enable-grub-pe2elf'. + +2008-08-08 Robert Millan + + * kern/disk.c: Replace `' with `'. + (grub_last_time): Change type to grub_uint64_t. + (grub_disk_open): Migrate code from to using grub_get_time_ms(). + (grub_disk_close): Likewise. + + * normal/menu.c: Replace `' with `'. + (run_menu): Migrate code from to using grub_get_time_ms(). + + * util/misc.c (grub_get_time_ms): New function. + +2008-08-08 Marco Gerards + + * disk/ata.c (grub_ata_regget): Change return type to + `grub_uint8_t'. + (grub_ata_regget2): Likewise. + (grub_ata_wait_status): New function. + (grub_ata_wait_busy): Removed function, updated all users to use + `grub_ata_wait_status'. + (grub_ata_wait_drq): Likewise. + (grub_ata_cmd): New function. + (grub_ata_pio_read): Change return type to `grub_uint8_t'. Add + error handling. + (grub_ata_pio_write): Add error handling. + (grub_atapi_identify): Likewise. + (grub_atapi_packet): Use `grub_ata_cmd' and improve error + handling. + (grub_ata_identify): Use `grub_ata_cmd' and improve error + handling. Actually use the detected registers. Reorder the + detection logic such that it is easier to read. + (grub_ata_pciinit): Do not assign the same ID to each controller. + (grub_ata_setaddress): Use `grub_ata_cmd' and improve error + handling. + (grub_atapi_readsector): Check the result of `grub_ata_pio_read'. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TIMEOUT'. + +2008-08-08 Marco Gerards + + * NEWS: Update. + +2008-08-07 Bean + + * include/grub/x86_64/pci.h: New file. + +2008-08-07 Christian Franke + + * kern/i386/pit.c (TIMER2_SPEAKER): New define. + (TIMER2_GATE): Likewise. + (grub_pit_wait): Add enable/disable of the timer2 gate + bit of port 0x61. This fixes a possible infinite loop. + +2008-08-07 Bean + + * conf/x86_64-efi.rmk (kernel_mod_SOURCES): Add kern/time.c, + kern/i386/tsc.c and kern/i386/pit.c. + + * include/grub/i386/tsc.h (grub_cpu_is_cpuid_supported): Handle + x86_64 platform. + + * kern/i386/efi/init.c: Replace with + . + + * kern/i386/pit.c: Replace with . + +2008-08-07 Bean + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Add kern/time.c. + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add kern/time.c, + + * include/grub/i386/pit.h: Use macro KERNEL_CPU_PIT_HEADER to avoid + multiple inclusion. Add #include . + +2008-08-06 Christian Franke + + * conf/common.rmk: Build and install `10_windows'. + * util/grub.d/10_windows.in: New script. + +2008-08-06 Pavel Roskin + + * kern/i386/pit.c: Include `'. + +2008-08-06 Robert Millan + + * conf/i386-coreboot.rmk (kernel_elf_ASFLAGS): New variable. + * kern/i386/tsc.c: Include `'. + +2008-08-06 Bean + + * fs/i386/pc/pxe.c (grub_pxe_data): New member block_size. + (grub_pxefs_fs_int): Remove dummy definition. + (grub_pxefs_open): Use data->block_size to store the current block + size setting. + (grub_pxefs_read): Use block size stored in data->block_size. As the + value of grub_pxe_blksize can be changed after the file is opened. + +2008-08-06 Bean + + * fs/i386/pc/pxe.c (curr_file): new variable. + (grub_pxefs_open): Simply the handling of pxe file system. Don't + require the dummy internal file system anymore. + (grub_pxefs_read): Removed. + (grub_pxefs_close): Likewise. + (grub_pxefs_fs_int): Likewise. + (grub_pxefs_read_int): Renamed to grub_pxefs_read. Reinitialize tftp + connection when we switch file. + (grub_pxefs_close_int): Renamed to grub_pxefs_close. + +2008-08-06 Robert Millan + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add `reboot.mod' and + `halt.mod'. + (reboot_mod_SOURCES, reboot_mod_CFLAGS, reboot_mod_LDFLAGS) + (halt_mod_SOURCES, halt_mod_CFLAGS, halt_mod_LDFLAGS): New variables. + + * kern/i386/halt.c: New file. + * kern/i386/reboot.c: Likewise. + * include/grub/i386/reboot.h: Likewise. + * include/grub/i386/halt.h: Likewise. + + * commands/halt.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI]: + Include `'. + * commands/reboot.c [! GRUB_MACHINE_IEEE1275 ! GRUB_MACHINE_EFI] + [! GRUB_MACHINE_PCBIOS]: Include `'. + + * term/i386/pc/at_keyboard.c: Include `'. + (SHIFT_L, SHIFT_R, CTRL, ALT, CAPS_LOCK, KEYBOARD_REG_DATA) + (KEYBOARD_REG_STATUS, KEYBOARD_COMMAND_ISREADY, KEYBOARD_COMMAND_READ) + (KEYBOARD_COMMAND_WRITE, KEYBOARD_COMMAND_REBOOT) + (KEYBOARD_SCANCODE_SET1, KEYBOARD_ISMAKE, KEYBOARD_ISREADY) + (KEYBOARD_SCANCODE, OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): Move + from here ... + * include/grub/i386/at_keyboard.h: ... to here. + +2008-08-05 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pit.c'. + * conf/i386-efi.rmk (kernel_mod_SOURCES): Likewise. + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Likewise. Also add + `kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and + `kern/generic/millisleep.c'. + + * kern/i386/tsc.c (calibrate_tsc): Rewrite using grub_pit_wait() + instead of grub_get_rtc(). + (grub_tsc_init): Initialize `tsc_boot_time'. + + * kern/i386/linuxbios/init.c (grub_millisleep): Remove stub. + (grub_machine_init): Use grub_tsc_init() rather than + installing an RTC-based handler via grub_install_get_time_ms(). + + * kern/i386/pit.c: New file. + * include/grub/i386/pit.h: Likewise. + +2008-08-05 Bean + + * boot/i386/pc/pxeboot.S (_start): Use drive number 0x7F for pxe. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Add machine/pxe.h. + (pkglib_MODULES): Add pxe.mod and pxecmd.mod. + (pxe_mod_SOURCES): New macro. + (pxe_mod_CFLAGS): Likewise. + (pxe_mod_LDFLAGS): Likewise. + (pxecmd_mod_SOURCES): Likewise. + (pxecmd_mod_CFLAGS): Likewise. + (pxecmd_mod_LDFLAGS): Likewise. + + * kern/i386/pc/startup.S (grub_pxe_scan): New function. + (grub_pxe_call): Likewise. + + * include/grub/disk.h (grub_disk_dev_id): Add GRUB_DISK_DEVICE_PXE_ID. + + * commands/i386/pc/pxecmd.c: New file. + + * fs/i386/pc/pxe.c: Likewise. + + * include/grub/i386/pc/pxe.h: Likewise. + +2008-08-05 Bean + + * util/console.c (grub_console_cur_color): New variable. + (grub_console_standard_color): Likewise. + (grub_console_normal_color): Likewise. + (grub_console_highlight_color): Likewise. + (color_map): Likewise. + (use_color): Likewise. + (NUM_COLORS): New macro. + (grub_ncurses_setcolorstate): Handle color properly. + (grub_ncurses_setcolor): Don't change color here, just remember the + settings, color will be set in grub_ncurses_setcolorstate. + (grub_ncurses_getcolor): New function. + (grub_ncurses_init): Initialize color pairs. + (grub_ncurses_term): New member grub_ncurses_getcolor. + +2008-08-05 Colin D Bennett + + High resolution timer support. Implemented for x86 CPUs using TSC. + Extracted generic grub_millisleep() so it's linked in only as needed. + This requires a Pentium compatible CPU; if the RDTSC instruction is + not supported, then it falls back on the generic grub_get_time_ms() + implementation that uses the machine's RTC. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/time.c', + `kern/i386/tsc.c', `kern/generic/rtc_get_time_ms.c' and + `kern/generic/millisleep.c'. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Add `kern/i386/tsc.c', + `kern/generic/rtc_get_time_ms.c' and `kern/generic/millisleep.c'. + + * conf/x86_64-efi.rml (kernel_mod_SOURCES): Add + `kern/generic/millisleep.c' and `kern/generic/rtc_get_time_ms.c'. + + * conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Add + `kern/generic/millisleep.c'. + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + + * conf/i386-coreboot.rmk (kernel_elf_SOURCES): Add `kern/time.c'. + + * kern/generic/rtc_get_time_ms.c: New file. + + * kern/generic/millisleep.c: New file. + + * kern/misc.c: Don't include + anymore. + (grub_millisleep_generic): Removed. + + * commands/sleep.c (grub_interruptible_millisleep): Uses + grub_get_time_ms() instead of grub_get_rtc(). + + * include/grub/i386/tsc.h (grub_get_tsc): New file. New inline + function. + (grub_cpu_is_cpuid_supported): New inline function. + (grub_cpu_is_tsc_supported): New inline function. + (grub_tsc_init): New function prototype. + (grub_tsc_get_time_ms): New function prototype. + + * kern/i386/tsc.c (grub_get_time_ms): New file. + + * include/grub/time.h: Include . Don't include + anymore. + (grub_millisleep): Removed. + (grub_machine_init): Call grub_tsc_init. + + * kern/i386/linuxbios/init.c (grub_machine_init): Install the RTC + get_time_ms() implementation. + + * kern/sparc64/ieee1275/init.c (grub_millisleep): Removed. + (ieee1275_get_time_ms): New function. + (grub_machine_init): Install get_time_ms() implementation. + + * kern/i386/pc/init.c: Include . + (grub_machine_init): Call grub_tsc_init(). + (grub_millisleep): Removed. + + * kern/ieee1275/init.c (grub_millisleep): Removed. + (grub_machine_init): Install ieee1275_get_time_ms() + implementation. + (ieee1275_get_time_ms): New function. + (grub_get_rtc): Now calls ieee1275_get_time_ms(), which does the + real work. + +2008-08-05 Marco Gerards + + * disk/ata.c: Include . + (enum grub_ata_commands): Add `GRUB_ATA_CMD_EXEC_DEV_DIAGNOSTICS'. + (grub_ata_initialize): Rewritten. + (grub_ata_device_initialize): New function. + +2008-08-04 Pavel Roskin + + * kern/main.c: Include grub/mm.h. + +2008-08-04 Robert Millan + + * conf/i386-coreboot.rmk (COMMON_ASFLAGS, COMMON_CFLAGS) + (COMMON_LDFLAGS): Harmonize with i386-pc version (fixes a code + corruption problem). + +2008-08-04 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Fix misc + warnings introduced in my last commit. + +2008-08-03 Robert Millan + + Make PCI available on all i386 architectures. + + * include/grub/i386/pc/pci.h: Move from here ... + * include/grub/i386/pci.h: ... to here. + + * include/grub/i386/pc/pci.h: Remove. + * include/grub/i386/efi/pci.h: Remove. + * include/grub/x86_64/efi/pci.h: Remove. + + * include/grub/pci.h: Replace `' with + `'. + + * conf/i386-coreboot.rmk (pkglib_MODULES): Add `pci' and `lspci'. + (pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS, lspci_mod_SOURCES) + (lspci_mod_CFLAGS, lspci_mod_LDFLAGS): New variables. + + * conf/i386-ieee1275.rmk: Likewise. + +2008-08-03 Robert Millan + + * term/i386/pc/vga_text.c (CRTC_CURSOR_DISABLE): New macro. + (grub_console_setcursor): Make it possible to set cursor off. + +2008-08-03 Robert Millan + + * util/grub.d/00_header.in: Be platform-agnostic. Probe for existence + of modules instead of assuming which platform provides what. + * util/update-grub.in: Likewise. + +2008-08-03 Robert Millan + + * kern/i386/pc/init.c (make_install_device): Check for `grub_prefix' + instead of `grub_install_dos_part' to determine whether a drive needs + to be prepended to prefix (`grub_install_dos_part' is not reliable, + because it can be overridden when loading GRUB via Multiboot). + +2008-08-02 Robert Millan + + * util/i386/pc/grub-install.in: Remove trailing slash from prefix. + +2008-08-02 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Add a pair + of informational grub_dprintf() calls. + +2008-08-02 Robert Millan + + * disk/memdisk.c (memdisk_size): Don't initialize. + (GRUB_MOD_INIT(memdisk)): Find memdisk using grub_module_iterate(). + + * include/grub/i386/pc/kernel.h + (GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): Remove macro. + (GRUB_KERNEL_MACHINE_PREFIX, GRUB_KERNEL_MACHINE_DATA_END): Shift. + (grub_memdisk_image_size, grub_arch_memdisk_addr) + (grub_arch_memdisk_size): Remove. + + * include/grub/kernel.h (struct grub_module_header): Remove `offset' + field (was only used to transfer a constant). Add `type' field to + support multiple module types. + (grub_module_iterate): New function. + + * kern/device.c (grub_device_open): Do not hide error messages + when grub_disk_open() fails. Use grub_print_error() instead. + + * kern/i386/pc/init.c (grub_arch_modules_addr) + (grub_arch_memdisk_size): Remove functions. + (grub_arch_modules_addr): Return the module address in high memory + (now that it isn't copied anymore). + + * kern/i386/pc/startup.S (grub_memdisk_image_size): Remove variable. + (codestart): Don't add grub_memdisk_image_size to %ecx in LZMA + decompression routine (grub_total_module_size already includes that + now). Don't copy modules back to low memory. + + * kern/main.c: Include `'. + (grub_load_modules): Split out (and use) ... + (grub_module_iterate): ... this function, which iterates through + module objects and runs a hook. + Comment out grub_mm_init_region() call, as it would cause non-ELF + modules to be overwritten. + + * util/i386/pc/grub-mkimage.c (generate_image): Instead of appending + the memdisk image in its own region, make it part of the module list. + * util/elf/grub-mkimage.c (options): Add "memdisk"|'m' option. + (main): Parse --memdisk|-m option, and pass user-provided path as + parameter to generate_image(). + (add_segments): Pass `memdisk_path' down to load_modules(). + (load_modules): Embed memdisk image in module section when requested. + * util/i386/efi/grub-mkimage.c (make_mods_section): Initialize + `header.type' instead of `header.offset'. + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add `memdisk.mod'. + (memdisk_mod_SOURCES, memdisk_mod_CFLAGS) + (memdisk_mod_LDFLAGS): New variables. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + +2008-08-02 Robert Millan + + * loader/i386/pc/multiboot.c (playground, forward_relocator) + (backward_relocator): New variables. Used to allocate and relocate + the payload, respectively. + (grub_multiboot_load_elf32): Load into heap instead of requested + address, install the appropriate relocator code in each bound of + the payload, and set the entry point such that + grub_multiboot_real_boot() will jump to one of them. + + * kern/i386/loader.S (grub_multiboot_payload_size) + (grub_multiboot_payload_orig, grub_multiboot_payload_dest) + (grub_multiboot_payload_entry_offset): New variables. + (grub_multiboot_real_boot): Set cpu context to what the relocator + expects, and jump to the relocator instead of the payload. + + * include/grub/i386/loader.h (grub_multiboot_payload_size) + (grub_multiboot_payload_orig, grub_multiboot_payload_dest) + (grub_multiboot_payload_entry_offset): Export. + +2008-08-01 Bean + + * normal/menu_entry.c (editor_getline): Don't return the original + string as result, as it will be released by lexer once it has done + using it. + +2008-08-01 Robert Millan + + * util/grub.d/10_linux.in: Use prepare_grub_to_access_device() from + within menuentries, not before them. + util/grub.d/10_hurd.in: Likewise. + +2008-08-01 Bean + + * conf/common.rmk (pkglib_MODULES): Add bufio.mod. + (bufio_mod_SOURCES): New macro. + (bufio_mod_CFLAGS): Likewise. + (bufio_mod_LDFLAGS): Likewise. + + * include/grub/bufio.h: New file. + + * io/bufio.c: Likewise. + + * video/png.c: Replace with . + (grub_video_reader_png): Use grub_buffile_open to open file. + + * video/jpeg.c: Replace with . + (grub_video_reader_jpeg): Use grub_buffile_open to open file. + + * video/tga.c: Replace with . + (grub_video_reader_tga): Use grub_buffile_open to open file. + + * font/manager.c: Include . + (add_font): Use grub_buffile_open to open file. + +2008-07-31 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): When loading + ELF segments, use a macro for arbitrarily accessing any of them instead + of preparing a pointer that allows access to one at a time. + (grub_multiboot_load_elf64): Likewise. + +2008-07-31 Bean + + * boot/i386/pc/lnxboot.S (real_code_2): Replace 0x50 with + GRUB_KERNEL_MACHINE_DATA_END. + +2008-07-30 Robert Millan + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_DATA_END): + Increase from 0x50 to 0x60. + * util/i386/pc/grub-install.in: Detect cross-disk installs, and + use UUIDs to identify the root drive for them. If that's not + possible, abort. + * util/i386/pc/grub-setup.c (setup): Do not special-case, or even + check, for cross-disk installs. + +2008-07-30 Robert Millan + + * kern/ieee1275/init.c (grub_machine_set_prefix): If `grub_prefix' + is non-empty, use it to set the `prefix' environment variable instead + of the usual approach. + * kern/i386/linuxbios/init.c (make_install_device): Remove function. + (grub_machine_set_prefix): Use `grub_prefix' to set the `prefix' + environment variable instead of dummy make_install_device(). + + * kern/i386/ieee1275/startup.S: Include `'. + (start): Insert a data section, with `grub_prefix' variable. + * kern/i386/linuxbios/startup.S: Likewise. + + * include/grub/powerpc/ieee1275/kernel.h [!ASM_FILE] (grub_prefix): + New variable reference. + * include/grub/i386/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_PREFIX): + New macro. Defines offset of `grub_prefix' within startup.S (relative + to `start'). + (GRUB_KERNEL_MACHINE_DATA_END): New macro. Defines the end of data + section within startup.S (relative to `start'). + * include/grub/i386/coreboot/kernel.h: Likewise. + + * util/elf/grub-mkimage.c (add_segments): Receive `prefix' parameter. + Overwrite grub_prefix with its contents, at the beginning of the + first segment. + (main): Understand -p|--prefix. + +2008-07-30 Robert Millan + + * util/grub.d/10_hurd.in: Source ${libdir}/grub/update-grub_lib. + +2008-07-30 Robert Millan + + * term/i386/pc/vga_text.c (grub_console_cls): Use + grub_console_gotoxy() to go back to beginning of the screen. + Found by Patrick Georgi + +2008-07-29 Christian Franke + + * util/update-grub_lib.in (make_system_path_relative_to_its_root): + Add conversion of emulated mount points on Cygwin. + +2008-07-29 Christian Franke + + * util/update-grub.in: Add a check for admin + group on Cygwin. + Remove old `grub.cfg.new' before creation. + Add `-f' to `mv' to handle the different filesystem + semantics of Windows. + +2008-07-29 Bean + + * normal/main.c (get_line): Fix buffer overflow bug. + +2008-07-28 Robert Millan + + * partmap/apple.c (GRUB_APPLE_HEADER_MAGIC): New macro. + (struct grub_apple_header): New struct. Describes the layout of + the partmap header. + (apple_partition_map_iterate): Check the header magic as well as the + partition magic (which was already being checked). + +2008-07-28 Pavel Roskin + + * genmk.rb: Add a warning to the beginning of the output that + it's a generated file and should not be edited. + +2008-07-28 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Do not abort when two disks + with the same number are found, just use issue a warning with + grub_dprintf(), as this error has been reported to be non-fatal. + +2008-07-27 Robert Millan + + * disk/ata.c (grub_ata_dumpinfo): Use grub_dprintf() for debugging + information. + +2008-07-27 Bean + + * fs/fat.c (GRUB_FAT_MAXFILE): New constant. + (grub_fat_find_dir): Ignore case when comparing filename. + +2008-07-27 Bean + + * fs/xfs.c (grub_xfs_dir_header): Change field i8count back to + smallino, as it's more descriptive, and i8count can be confused with + the other field count. + (grub_xfs_iterate_dir): Adjust grub_xfs_dir_entry pointer for small + inode type. + +2008-07-27 Bean + + * commands/crc.c: New file. + + * lib/crc.c: Likewise. + + * include/grub/lib/crc.h: Likewise. + + * util/grub-fstest.c: grub/hexdump.h => grub/lib/hexdump.h. + + * commands/hexdump.c: grub/hexdump.h => grub/lib/hexdump.h. + (hexdump): Move this function to ... + + * lib/hexdump.c: ... here. + + * include/grub/hexdump.h: Renamed to ... + + * include/grub/lib/hexdump.h: ... this. + + * commands/loadenv.c: grub/envblk.h => grub/lib/envblk.h + + * util/grub-editenv.c: Likewise. + + * include/envblk.h: Renamed to ... + + * include/lib/envblk.h: ... this. + + * util/envblk.c: Renamed to ... + + * lib/envblk.c: ... this. + + * conf/common.rmk (grub_fstest_SOURCES): commands/hexdump.c => + lib/hexdump.c. + (grub_editenv_SOURCES): util/envblk.c => lib/envblk.c + (pkglib_MODULES): Add crc.mod. + (hexdump_mod_SOURCES): Add lib/hexdump.c. + (loadenv_mod_SOURCES): util/envblk.c => lib/envblk.c. + (crc_mod_SOURCES): New macro. + (crc_mod_CFLAGS): Likewise. + (crc_mod_LDFLAGS): Likewise. + + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add lib/hexdump.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise. + +2008-07-27 Felix Zielcke + + * commands/help.c: Include . + (TERM_WIDTH): Removed. Updated all users. + +2008-07-27 Pavel Roskin + + * util/getroot.c (find_root_device): Rephrase a comment to avoid + spurious warnings about a comment within a comment. + +2008-07-25 Robert Millan + + * util/getroot.c (find_root_device): Skip devices that match + /dev/dm-[0-9]. This lets the real device be found for any type of + abstraction (LVM, EVMS, RAID..). + (grub_guess_root_device): Do not traverse /dev/mapper (for LVM) + and /dev/evms (for EVMS) before traversing /dev. If a /dev/dm-[0-9] + device is found first, find_root_device() will now skip it. + +2008-07-24 Pavel Roskin + + * include/grub/types.h: Use __builtin_bswap32() and + __builtin_bswap64() with gcc 4.3 and newer. + +2008-07-24 Christian Franke + + * util/i386/pc/grub-install.in: If `--debug' is specified, + pass `--verbose' to grub-setup. + Abort script if make_system_path_relative_to_its_root() fails. + +2008-07-24 Bean + + * configure.ac: Fixed a bug caused by the previous cygwin patch, + variable `target_platform' should be `platform'. + +2008-07-24 Bean + + * video/reader/png.c (DEFLATE_HLIT_MAX): Change value. + (grub_png_init_fixed_block): New function. + (grub_png_decode_image_data): Handle fixed huffman code compression. + +2008-07-24 Bean + + * common.rmk (bin_UTILITIES): Add grub-pe2elf. + (grub_pe2elf_SOURCES): New macro. + (CLEANFILES): Add grub-pe2elf. + + * include/grub/efi/pe32.h (GRUB_PE32_SCN_ALIGN_1BYTES): New constant. + (GRUB_PE32_SCN_ALIGN_2BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_4BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_8BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_16BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_32BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_64BYTES): Likewise. + (GRUB_PE32_SCN_ALIGN_SHIFT): Likewise. + (GRUB_PE32_SCN_ALIGN_MASK): Likewise. + (GRUB_PE32_SYM_CLASS_EXTERNAL): Likewise. + (GRUB_PE32_SYM_CLASS_STATIC): Likewise. + (GRUB_PE32_SYM_CLASS_FILE): Likewise. + (GRUB_PE32_DT_FUNCTION): Likewise. + (GRUB_PE32_REL_I386_DIR32): Likewise. + (GRUB_PE32_REL_I386_REL32): Likewise. + (grub_pe32_symbol): New structure. + (grub_pe32_reloc): Likewise. + + * util/grub-pe2elf.c: New file. + + * configure.ac: Set TARGET_OBJ2ELF if host os is cygwin. Don't test for + start symbol in non pc platform. + + * genmk.rb: Use TARGET_OBJ2ELF to convert native object format to elf. + + The following patches are from Christian Franke. + + * include/grub/dl.h: Remove .previous, gas supports this only + for ELF format. + + * include/grub/symbol.h [__CYGWIN__] (#define FUNCTION/VARIABLE): + Remove .type, gas supports this only for ELF format. + + * kern/dl.c (grub_dl_resolve_dependencies): Add check for trailing + nullbytes in symbol table. This fixes an infinite loop if table is + zero filled. + + * Makefile.in: Add autoconf replacements TARGET_IMG_LDSCRIPT, + TARGET_IMG_LDFLAGS and EXEEXT. + + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Replace -Wl,-N by + TARGET_IMG_LDFLAGS_AC. + (grub_CHECK_STACK_ARG_PROBE): New function. + + * conf/i386-pc.rmk: Replace -Wl,-N by TARGET_IMG_LDFLAGS. + + * conf/i386-pc-cygwin-ld-img.sc: New linker script. + + * configure.ac: Add check for linker script "conf/${target}-img-ld.c" + to set TARGET_IMG_LD* accordingly. + Add check for Cygwin to set TARGET_MOD_OBJCOPY accordingly. + Add call to grub_CHECK_STACK_ARG_PROBE. + Use TARGET_IMG_LDFLAGS to check start, bss_start, end symbols. + + * genkernsyms.sh.in: Handle HAVE_ASM_USCORE case. + + * genmk.rb: Add EXEEXT to CLEANFILES. + +2008-07-23 Robert Millan + + * Makefile.in (UNICODE_ARROWS, UNICODE_LINES): New variables (they + define the codes for arrows and lines used for the menu). + (ascii.pff): Generate fonts for $(UNICODE_ARROWS) and $(UNICODE_LINES) + as well. + + * util/update-grub_lib.in (font_path): Prefer ascii.pff over complete + fonts, because the latter are too slow. + +2008-07-21 Bean + + * kern/i386/pc/startup.S (gate_a20_try_bios): Change test order for + a20. Run keyboard test last, as it will cause macbook to halt. + +2008-07-18 Pavel Roskin + + * kern/dl.c: Go back to using GRUB_CPU_SIZEOF_VOID_P. We cannot + load foreign architecture modules correctly anyway. Keep + support for loading host architecture modules, whether we + compile them or not. + +2008-07-17 Pavel Roskin + + * configure.ac: Use -m32 or -m64 regardless of whether we had to + change target_cpu. The compiler default can mismatch target_cpu + in any case. + + * disk/efi/efidisk.c: Fix format warnings on x86_64. + * kern/efi/efi.c: Likewise. + + * aclocal.m4 (grub_PROG_TARGET_CC): New macro. Check if the + target compiler is functional. + * configure.ac: Call grub_PROG_TARGET_CC once all target flags + are set up. + + * configure.ac: Default to efi platform for x86_64-apple. Allow + powerpc64 CPU, default to ieee1275 platform for it. Split CPU + adjustments from the rest, only do them if target is not + explicitly given. Merge other adjustments with the final sanity + check. Remove an extraneous check for supported CPU. Be + specific which CPU and which platform is not supported. + + * configure.ac: Default to pc platform for x86_64. + +2008-07-17 Robert Millan + + Partial LinuxBIOS -> Coreboot rename. + + * conf/i386-linuxbios.rmk: Renamed to ... + * conf/i386-coreboot.rmk: ... this. + * Makefile.in (RMKFILES): s/i386-linuxbios.rmk/i386-coreboot.rmk/g. + * configure.ac: Accept "coreboot" as input platform (but maintain + compatibility with "linuxbios"). + * include/grub/i386/linuxbios: Renamed to ... + * include/grub/i386/coreboot: ... this. + +2008-07-17 Bean + + * conf/i386/efi.rmk (pkglib_MODULES): add pci.mod and lspci.mod. + (appleldr_mod_SOURCE): New variable. + (appleldr_mod_CFLAGS): Likewise. + (appleldr_mod_LDFLAGS): Likewise. + (pci_mod_SOURCES): Likewise. + (pci_mod_CFLAGS): Likewise. + (pci_mod_LDFLAGS): Likewise. + (lspci_mod_SOURCES): Likewise. + (lspci_mod_CFLAGS): Likewise. + (lspci_mod_LDFLAGS): Likewise. + + * conf/x86_64-efi.rmk: New file. + + * disk/efi/efidisk.c (grub_efidisk_read): Wrap efi calls with efi_call_N + macro. + (grub_efidisk_write): Likewise. + + * include/efi/api.h (efi_call_0): New macro. + (efi_call_1): Likewise. + (efi_call_2): Likewise. + (efi_call_3): Likewise. + (efi_call_4): Likewise. + (efi_call_5): Likewise. + (efi_call_6): Likewise. + + * include/grub/efi/chainloader.h (grub_chainloader_cmd): Rename to + grub_rescue_cmd_chainloader. + + * include/grub/efi/pe32.h (GRUB_PE32_MACHINE_X86_64): New macro. + (grub_pe32_optional_header): Change some fields based on i386 or + x86_64 platform. + (GRUB_PE32_PE32_MAGIC): Likewise. + + * include/grub/efi/uga_draw.h: New file. + + * include/grub/elf.h (STN_ABS): New constant. + (R_X86_64_NONE): Relocation constant for x86_64. + (R_X86_64_64): Likewise. + (R_X86_64_PC32): Likewise. + (R_X86_64_GOT32): Likewise. + (R_X86_64_PLT32): Likewise. + (R_X86_64_COPY): Likewise. + (R_X86_64_GLOB_DAT): Likewise. + (R_X86_64_JUMP_SLOT): Likewise. + (R_X86_64_RELATIVE): Likewise. + (R_X86_64_GOTPCREL): Likewise. + (R_X86_64_32): Likewise. + (R_X86_64_32S): Likewise. + (R_X86_64_16): Likewise. + (R_X86_64_PC16): Likewise. + (R_X86_64_8): Likewise. + (R_X86_64_PC8): Likewise. + + * include/grub/i386/efi/pci.h: New file. + + * include/grub/i386/linux.h (GRUB_LINUX_EFI_SIGNATURE): + Change it value based on platform. + (GRUB_LINUX_EFI_SIGNATURE_0204): New constant. + (GRUB_E820_RAM): Likewise. + (GRUB_E820_RESERVED): Likewise. + (GRUB_E820_ACPI): Likewise. + (GRUB_E820_NVS): Likewise. + (GRUB_E820_EXEC_CODE): Likewise. + (GRUB_E820_MAX_ENTRY): Likewise. + (grub_e820_mmap): New structure. + (linux_kernel_header): Change the efi field according to different + kernel version, also field from linux_kernel_header. + + * include/grub/kernel.h (grub_module_info): Add padding for x86_64. + + * include/grub/pci.h (GRUB_PCI_ADDR_SPACE_MASK): New constant. + (GRUB_PCI_ADDR_SPACE_MEMORY): Likewise. + (GRUB_PCI_ADDR_SPACE_IO): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_MASK): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_32): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_1M): Likewise. + (GRUB_PCI_ADDR_MEM_TYPE_64): Likewise. + (GRUB_PCI_ADDR_MEM_PREFETCH): Likewise. + (GRUB_PCI_ADDR_MEM_MASK): Likewise. + (GRUB_PCI_ADDR_IO_MASK): Likewise. + + * include/grub/x86_64/efi/kernel.h: New file. + + * include/grub/x86_64/efi/loader.h: Likewise. + + * include/grub/x86_64/efi/machine.h: Likewise. + + * include/grub/x86_64/efi/pci.h: Likewise. + + * include/grub/x86_64/efi/time.h: Likewise. + + * include/grub/x86_64/linux.h: Likewise. + + * include/grub/x86_64/setjmp.h: Likewise. + + * include/grub/x86_64/time.h: Likewise. + + * include/grub/x86_64/types.h: Likewise. + + * kern/dl.c (GRUB_CPU_SIZEOF_VOID_P): Changed to + GRUB_TARGET_SIZEOF_VOID_P. + + * kern/efi/efi.c (grub_efi_locate_protocol): Wrap efi calls. + (grub_efi_locate_handle): Likewise. + (grub_efi_open_protocol): Likewise. + (grub_efi_set_text_mode): Likewise. + (grub_efi_stall): Likewise. + (grub_exit): Likewise. + (grub_reboot): Likewise. + (grub_halt): Likewise. + (grub_efi_exit_boot_services): Likewise. + (grub_get_rtc): Likewise. + + * kern/efi/mm.c (MEMORY_MAP_SIZE): Change to 0x3000 for new models. + (GRUB_CPU_SIZEOF_VOID_P): Changed to GRUB_TARGET_SIZEOF_VOID_P. + (grub_efi_allocate_pages): Wrap efi calls. + (grub_efi_free_pages): Wrap efi calls. + (grub_efi_get_memory_map): Wrap efi calls. + + * kern/x86_64/dl.c: New file. + + * kern/x86_64/efi/callwrap.S: Likewise. + + * kern/x86_64/efi/startup.S: Likewise. + + * loader/efi/appleloader.c: Likewise. + + * loader/efi/chainloader.c (cmdline): New variable. + (grub_chainloader_unload): Wrap efi calls. + (grub_chainloader_boot): Likewise. + (grub_rescue_cmd_chainloader): Wrap efi calls, handle + command line. + + * loader/efi/chainloader_normal.c (chainloader_command): + Change grub_chainloader_cmd to grub_rescue_cmd_chainloader, pass + command line. + + * loader/i386/efi/linux.c (allocate_pages): Change allocation + method. + (grub_e820_add_region): New function. + (grub_linux_boot): Construct e820 map from efi map, handle x86_64 + booting. + (grub_find_video_card): New function. + (grub_linux_setup_video): New function. + (grub_rescue_cmd_linux): Probe for video information. + + * normal/x86_64/setjmp.S: New file. + + * term/efi/console.c (map_char): New function. + (grub_console_putchar): Map unicode char. + (grub_console_checkkey): Wrap efi calls. + (grub_console_getkey): Likewise. + (grub_console_getwh): Likewise. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Likewise. + (grub_console_setcolorstate): Likewise. + (grub_console_setcursor): Likewise. + + * util/i386/efi/grub-mkimage.c: Add support for x86_64. + +2008-07-16 Pavel Roskin + + * loader/i386/efi/linux.c (allocate_pages): Fix warnings in + format strings. + + * util/i386/efi/grub-mkimage.c (get_target_address): Return a + pointer, not an integer. This fixes a warning and prevents + precision loss on 64-bit systems. + (relocate_addresses): Remove unneeded cast. + +2008-07-15 Pavel Roskin + + * kern/i386/ieee1275/init.c: Include grub/cache.h. + + * term/ieee1275/ofconsole.c: Disable code unused on i386. + + * kern/ieee1275/ieee1275.c (grub_ieee1275_get_integer_property): + Fix comparison between signed and unsigned. + + * include/grub/i386/ieee1275/console.h: Declare + grub_console_init() and grub_console_fini(). + + * loader/i386/ieee1275/linux.c (grub_set_bootpath): Remove. + It's empty and unused. + + * fs/ext2.c (grub_ext2_read_block): Initialize blknr in the + beginning to avoid warnings with some compilers. + + * loader/ieee1275/multiboot2.c: Include grub/machine/loader.h. + [__i386__] (grub_mb2_arch_boot): Avoid unnecessary cast. + +2008-07-14 Pavel Roskin + + * kern/env.c (grub_register_variable_hook): Don't copy empty + string, it leaks memory. Pass "" to grub_env_set(), it should + handle constant strings. + + * commands/blocklist.c (grub_cmd_blocklist): Fix format warning. + * commands/cmp.c (grub_cmd_cmp): Likewise. + * kern/dl.c (grub_dl_flush_cache): Likewise. + (grub_dl_load_core): Likewise. + * kern/elf.c (grub_elf32_load_phdrs): Likewise. + (grub_elf64_load_phdrs): Likewise. + +2008-07-13 Pavel Roskin + + * lib/LzmaEnc.c (LzmaEnc_SetProps): Fix warning about comparison + between signed and unsigned. + (LzmaEnc_Finish): Fix warning about an unused parameter. + +2008-07-13 Bean + + * Makefile.in (enable_lzo): New rule. + + * conf/i386-pc.rmk (grub_mkimage_SOURCES): New test with enable_lzo. + + * configure.ac (ENABLE_LZO): New option --enable-lzo. + + * boot/i386/pc/lnxboot.S: #include . + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Change + its value according to the compression algorithm used, lzo or lzma. + + * util/i386/pc/grub-mkimage.c (compress_kernel): Use different + compression algorithm according to configure macro. + + * kern/i386/pc/startup.S (codestart): Likewise. + + * kern/i386/pc/lzma_decode.S: New file. + + * include/grub/lib/LzFind.h: Likewise. + + * include/grub/lib/LzHash.h: Likewise. + + * include/grub/lib/LzmaDec.h: Likewise. + + * include/grub/lib/LzmaEnc.h: Likewise. + + * include/grub/lib/LzmaTypes.h: Likewise. + + * lib/LzFind.c: Likewise. + + * lib/LzmaDec.c: Likewise. + + * lib/LzmaEnc.c: Likewise. + +2008-07-13 Bean + + * fs/ext2.c (EXT4_EXTENTS_FLAG): New macro. + (grub_ext4_extent_header): New structure. + (grub_ext4_extent): Likewise. + (grub_ext4_extent_idx): Likewise. + (grub_ext4_find_leaf): New function. + (grub_ext2_read_block): Handle extents. + +2008-07-12 Robert Millan + + * util/i386/pc/grub-mkrescue.in: s/grub-install/grub-mkrescue/g. + +2008-07-11 Robert Millan + + * util/grub.d/40_custom.in: New file. Example on how to add custom + entries to /etc/grub.d. + * conf/common.rmk (%, update-grub_SCRIPTS, CLEANFILES): Install + 40_custom (implicitly, by merging all the grub.d rules). + +2008-07-11 Pavel Roskin + + * commands/read.c (grub_getline): Fix invalid memory access. + Don't add newline to the variable value. + + * term/i386/pc/serial.c (GRUB_SERIAL_PORT_NUM): New constant. + [!GRUB_MACHINE_PCBIOS] (serial_hw_io_addr): Add COM2 and COM3. + (serial_hw_get_port): Check validity of the port number. + (grub_cmd_serial): Check return value of serial_hw_get_port(). + +2008-07-07 Pavel Roskin + + * boot/i386/pc/diskboot.S (notification_string): Replace + "Loading kernel" with just "loading". This is shorter, less + confusing and saves a few bytes for possible future changes. + +2008-07-05 Pavel Roskin + + * disk/ata.c (grub_ata_dumpinfo): Don't output addressing and + size for ATAPI devices, they are undefined. Output sector + number in decimal form. + + * disk/ata.c: Use named constants for status bits. + +2008-07-04 Pavel Roskin + + * kern/i386/linuxbios/init.c (grub_machine_init): Cast addr to + grub_addr_t before casting it to the void pointer to fix a + warning. Non-addressable regions are discarded earlier. + (grub_arch_modules_addr): Cast _end to grub_addr_t. + * kern/i386/linuxbios/table.c: Include grub/misc.h. + (check_signature): Don't shadow table_header. + (grub_linuxbios_table_iterate): Cast numeric constants to + grub_linuxbios_table_header_t. + * include/grub/i386/linuxbios/init.h: Add noreturn attribute to + grub_stop(). + + * kern/ieee1275/init.c: Cast _start and _end to grub_addr_t to + prevent warnings. + + * include/grub/misc.h (ALIGN_UP): Avoid unnecessary cast to a + pointer, which can cause warnings. Support 64-bit addresses. + + * util/elf/grub-mkimage.c: Use GRUB_TARGET_SIZEOF_LONG instead + of sizeof(long). This fixes PowerPC image generation on x86_64. + +2008-07-04 Robert Millan + + This fixes a performance issue when pc & gpt partmap iterators + didn't abort iteration even after our hook found what it was + looking for (often causing expensive probes of non-existent drives). + + Some callers relied on previous buggy behaviour, since they would + raise an error when their own hooks caused early abortion of its + iteration. + + * kern/device.c (grub_device_open): Improve error message. + * disk/lvm.c (grub_lvm_open): Likewise. + * disk/raid.c (grub_raid_open): Likewise. + + * partmap/pc.c (pc_partition_map_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. + (pc_partition_map_probe): Do not fail when find_func() caused + early abortion of pc_partition_map_iterate(). + + * partmap/gpt.c (gpt_partition_map_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. + (gpt_partition_map_probe): Do not fail when find_func() caused + early abortion of gpt_partition_map_iterate(). + + * kern/partition.c (grub_partition_iterate): Abort parent iteration + when hook requests it, independently of grub_errno. Do not fail when + part_map_iterate_hook() caused early abortion of p->iterate(). + + * util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Do not fail + when grub_partition_iterate() returned with non-zero. + +2008-07-03 Pavel Roskin + + * disk/ata.c (grub_ata_pio_write): Check status before writing, + like we do in grub_ata_pio_read(). + (grub_ata_readwrite): Always write individual sectors. Fix the + sector count for the remainder. + (grub_ata_write): Enable writing to ATA devices. Correctly + report error for ATAPI devices. + +2008-07-02 Pavel Roskin + + * boot/i386/pc/cdboot.S: Add _start entry to fix a linker + warning. + + * disk/ata.c (grub_ata_readwrite): Don't increment sector number + for every read sector, we already increment it for the whole + batch. This fixes reading more than 256 sectors at once. + + * util/grub-editenv.c (cmd_info): Cast argument to long + explicitly. ptrdiff_t reduces to int on i386. + + * util/grub-editenv.c (main): Be specific which parameter is + missing. + + * disk/memdisk.c (memdisk_addr): Make a pointer to fix warnings. + (memdisk): Make memdisk_orig_addr a pointer. + + * fs/reiserfs.c (grub_reiserfs_read): Fix misuse of grub_size_t + for file offsets, use grub_off_t instead. Fix printf format + warnings. + + * fs/reiserfs.c: Remove #warning, TODO list items don't belong + there. Real unexpected warnings should not drown in the noise + about known problems. + + * commands/hexdump.c (grub_cmd_hexdump): Fix misuse of + grub_disk_addr_t for memory addresses. + + * loader/aout.c (grub_aout_load): Cast load_addr to pointer + explicitly to fix a warning. + + * util/grub-editenv.c (cmd_info): Fix warning in printf format. + + * Makefile.in (MODULE_LDFLAGS): New variable. + * aclocal.m4 (grub_PROG_LD_BUILD_ID_NONE): New macro. Check if + the linker accepts --build-id=none. + * configure.ac: Call grub_PROG_LD_BUILD_ID_NONE. Substitute + MODULE_LDFLAGS. + * genmk.rb: Use MODULE_LDFLAGS when linking modules. + + * fs/xfs.c (struct grub_xfs_dir_header): Use names similar to + those in Linux XFS code. Provide a way to access 64-bit parent + inode. + (grub_xfs_iterate_dir): Use the new names. Avoid reading past + the end of struct grub_xfs_dir_header. + +2008-07-02 Bean + + * include/grub/ieee1275.h (grub_ieee1275_flag): New constant + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM + and GRUB_IEEE1275_FLAG_NO_ANSI. + + * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set flag + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, GRUB_IEEE1275_FLAG_FORCE_CLAIM + and GRUB_IEEE1275_FLAG_NO_ANSI for Open Hackware. + + * kern/ieee1275/ieee1275.c (grub_ieee1275_interpret): Return + immediately if GRUB_IEEE1275_FLAG_CANNOT_INTERPRET is set. + + * kern/ieee1275/init.c (grub_claim_heap): Claim memory directly if + GRUB_IEEE1275_FLAG_FORCE_CLAIM is set. + + * term/ieee1275/ofconsole.c (grub_ofconsole_writeesc): Don't output + esc sequence on non ANSI terminal. + (grub_ofconsole_gotoxy): Emulate backspace key on non ANSI terminal. + + * util/elf/grub-mkimage.c (add_segments): Move ELF header to the + beginning of file. + +2008-07-02 Bean + + * conf/common.rmk (bin_UTILITIES): Add grub-editenv. + (grub_editenv_SOURCES): New variable. + (pkglib_MODULES): Add loadenv.mod. + (loadenv_mod_SOURCES): New variable. + (loadenv_mod_CFLAGS): Likewise. + (loadenv_mod_LDFLAGS): Likewise. + + * include/grub/envblk.h: New file. + + * util/envblk.c: New file. + + * util/grub-editenv.c: New file. + + * commands/loadenv.c: New file. + +2008-07-01 Pavel Roskin + + * include/multiboot2.h (struct multiboot_tag_module): Use char, + not unsigned char. This fixes warnings and is consistent with + other tags. + + * disk/fs_uuid.c (search_fs_uuid): Correctly increment count. + + * normal/parser.y: Define YYENABLE_NLS as 0 to fix warnings. + + * term/tparm.c (analyze): Always set *popcount. + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Remove useless + cast to fix a warning. + + * loader/i386/pc/multiboot2.c (grub_mb2_arch_module_alloc): Use + cast to suppress a warning. + + * fs/afs.c (grub_afs_read_block): Return grub_disk_addr_t, as + grub_fshelp_read_file() expects. + + * fs/fat.c: Fix UUID calculation on big-endian systems. We + write uuid as a 32-bit value in CPU byte order, so declare and + use it as such. + + * disk/raid.c: Cast grub_dprintf() arguments to unsigned long + long if the format specifier expects it. + * partmap/gpt.c (gpt_partition_map_iterate): Likewise. + * partmap/pc.c (pc_partition_map_iterate): Likewise. + * fs/ntfs.c (grub_ntfs_uuid): Cast data->uuid to unsigned long + long to fix a warning. + * fs/reiserfs.c (grub_reiserfs_read): Change casts in + grub_dprintf() arguments to fix warnings. + +2008-06-30 Pavel Roskin + + * util/i386/pc/grub-setup.c (setup): Write install_dos_part and + install_bsd_part immediately before core.img is embedded or + modified on disk. This fixes core.img verification if core.img + cannot be embedded. + + * util/i386/pc/grub-setup.c (setup): Use core_path_dev, not + core_path to calculate the blocklist. + Patch from Javier Martín + +2008-06-29 Robert Millan + + * fs/xfs.c (GRUB_XFS_FSB_TO_BLOCK): New macro. Maps filesystem + block to disk block. + (grub_xfs_read_block): Use GRUB_XFS_FSB_TO_BLOCK() on result. + Patch from Niels Böhm + +2008-06-29 Robert Millan + + * util/update-grub_lib.in (font_path): Search for fonts in + /boot/grub first, which is more likely to be readable (we aren't + deciding where fonts live, just looking for them). + +2008-06-26 Pavel Roskin + + * util/biosdisk.c (read_device_map): Don't leave dead map + entries for devices failing stat() check. + + * util/i386/pc/grub-setup.c (setup): Don't reuse core_path, use + core_path_dev for the core.img path on the target device. + +2008-06-26 Robert Millan + + * disk/fs_uuid.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `fs_uuid.mod'. + (fs_uuid_mod_SOURCES, fs_uuid_mod_CFLAGS) + (fs_uuid_mod_LDFLAGS): New variables. + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_UUID_ID'. + * kern/disk.c (grub_disk_dev_iterate): Allow disk devices not to + implement iterate(). + +2008-06-26 Robert Millan + + * util/grub.d/10_linux.in: Avoid passing UUIDs to Linux when either + "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" does not exist, or when a + Linux image includes no initrd. + +2008-06-21 Javier Martín + + * util/i386/pc/grub-setup.c (setup): Remove literal "core.img" in a + call to resolve the core image location that effectively appended the + name twice. + +2008-06-21 Robert Millan + + * util/grub.d/00_header.in: Move last prepare_grub_to_access_device() + call from here ... + + * util/grub.d/10_hurd.in: ... to here ... + * util/grub.d/10_linux.in: ... and here. + +2008-06-19 Robert Millan + + * kern/main.c (grub_main): Export `prefix' variable immediately + after it has been set by grub_machine_set_prefix(). + +2008-06-19 Robert Millan + + * commands/search.c (search_label, search_fs_uuid, search_file): Print + search result when not saving to variable, not the other way around. + When saving to variable, abort iteration as soon as a match is found. + +2008-06-19 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Remove + check for partition that provides /boot/grub. Its logic is flawed, + as it prevents prepare_grub_to_access_device() from being called + multiple times. + +2008-06-19 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Issue + "insmod" command directly when abstraction modules are needed, + instead of relying on GRUB_PRELOAD_MODULES (which had no effect + since it had already been processed). + +2008-06-19 Pavel Roskin + + * conf/i386-efi.rmk: Recompile grub-mkimage.c if Makefile has + changed. This is needed in case GRUB_LIBDIR changes. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + +2008-06-18 Pavel Roskin + + * conf/powerpc-ieee1275.rmk (kernel_elf_SOURCES): Rename + kernel_elf_symlist.c to symlist.c for consistency with other + architectures. Update all users. + * conf/sparc64-ieee1275.rmk (kernel_elf_SOURCES): Likewise. + +2008-06-18 Robert Millan + + * util/i386/pc/grub-install.in: If the drive is LVM or RAID, prepend + it in prefix. + + * util/i386/pc/grub-setup.c (main): Don't handle prefix at all. Set + `must_embed' to 1 when root_dev is a RAID device. When dest_dev is + a RAID device, run setup() for all members independently on whether + LVM abstraction is being used. + (setup): Don't handle prefix at all; let grub-mkimage take care of it. + If grub-mkimage has set `*install_dos_part == -2', don't override this + value. + Perform *install_dos_part adjustments independently on whether + we're embedding or not. + Clarify error message when image is too big for embedding. + Remove duplicate *install_dos_part stanza. + +2008-06-17 Robert Millan + + * term/ieee1275/ofconsole.c (fgcolor, bgcolor): Remove variables. + (grub_ofconsole_normal_color, grub_ofconsole_highlight_color): New + variables. + (grub_ofconsole_setcolor, grub_ofconsole_getcolor): Load/store + values in grub_ofconsole_normal_color and + grub_ofconsole_highlight_color (they're not directly related to + background and foreground). + (grub_ofconsole_setcolorstate): Extract background and foreground + from grub_ofconsole_normal_color and grub_ofconsole_highlight_color. + +2008-06-17 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Use + /boot/grub for the check in last commit, not /boot (they could be + different partitions). + +2008-06-16 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): If we were + asked to setup access for the same partition that provides /boot, + don't bother using UUIDs since our root already has the value we + want. + +2008-06-16 Robert Millan + + * util/biosdisk.c (convert_system_partition_to_system_disk): Detect + I2O devices. + Patch from Sven Mueller . + +2008-06-16 Robert Millan + + * util/update-grub.in: Check for $EUID instead of $UID. + Reported by Vincent Zweije. + +2008-06-16 Bean + + * fs/ext2.c (grub_ext2_blockgroup): Revert to pre-journal state. + (grub_ext2_read_block): Likewise. + (grub_ext2_read_inode): Likewise. + (grub_ext2_mount): Likewise. + (grub_ext2_close): Likewise. + (grub_ext3_get_journal): Removed. + + * fs/reiserfs.c (grub_reiserfs_get_item): Revert to pre-journal state. + (grub_reiserfs_read_symlink): Likewise. + (grub_reiserfs_mount): Likewise. + (grub_reiserfs_open): Likewise. + (grub_reiserfs_read): Likewise. + (grub_reiserfs_close): Likewise. + (grub_reiserfs_get_journal): Removed. + + * fs/fshelp.c (grub_fshelp_read): Removed. + (grub_fshelp_map_block): Likewise. + + * include/grub/fshelp.h (grub_fshelp_journal_type): Removed. + (grub_fshelp_journal): Likewise. + (grub_fshelp_read): Likewise. + (grub_fshelp_map_block): Likewise. + +2008-06-16 Pavel Roskin + + * conf/powerpc-ieee1275.rmk: Remove -msoft-float, we don't use + floating point anymore. + * include/grub/powerpc/libgcc.h: Leave only necessary exports. + +2008-06-15 Pavel Roskin + + * commands/ls.c (grub_ls_list_files): Use integer calculations + for human readable format, avoid floating point use. + * kern/misc.c (grub_ftoa): Remove. + (grub_vsprintf): Remove floating point support. + +2008-06-15 Robert Millan + + * util/grub.d/10_linux.in: Use the underlying device for loop-AES + devices. + Reported by Max Vozeler. + +2008-06-15 Robert Millan + + * util/i386/pc/grub-mkimage.c (generate_image): If we included a drive + in our prefix, set install_{dos,bsd}_part = -2 to indicate this can be + skipped later. + (main): If a memdisk was requested, add "(memdisk)" drive explicitly to + the beginning of the prefix. + + * kern/i386/pc/init.c (make_install_device): Remove memdisk check. + It is assumed that if we have a memdisk, grub-mkimage has set + grub_prefix to include the "(memdisk)" drive in it. + +2008-06-15 Robert Millan + + * term/i386/pc/console.c [GRUB_MACHINE_LINUXBIOS] (grub_console_init): + Initialize keyboard controller after registering the terminal, so that + grub_printf() can be called from grub_keyboard_controller_init(). + +2008-06-15 Robert Millan + + * fs/sfs.c (grub_sfs_read_extent): Fix the count of nodes in + extent-btree which is written as big endian on disk. + Reported by Alain Greppin . + +2008-06-14 Robert Millan + + * util/i386/efi/grub-install.in (modules): Remove `_chain'. + * util/i386/pc/grub-install.in (modules): Likewise. + +2008-06-13 Pavel Roskin + + * commands/ls.c (grub_ls_list_files): Fix format warnings. + +2008-06-13 Bean + + * commands/hexdump.c (grub_cmd_hexdump): Adjust offset for partition. + + * fs/ext2.c (grub_ext3_get_journal): Fix revoke block handling. + + * fs/fshelp.c (grub_fshelp_map_block): Don't map block 0 as it's used + to indicate sparse block. + +2008-06-12 Pavel Roskin + + * fs/ext2.c (grub_ext2_read_inode): Don't normalize block + number, grub_fshelp_read() does it for us. + + * fs/fshelp.c (grub_fshelp_read): New function. Implement + linear disk read with journal translation. + * fs/ext2.c: Use grub_fshelp_read() instead of grub_disk_read(). + * include/grub/fshelp.h: Declare grub_fshelp_read(). + +2008-06-09 Pavel Roskin + + * fs/minix.c (grub_minix_mount): Handle error reading + superblock. + +2008-06-08 Robert Millan + + * util/i386/pc/grub-setup.c (main): If install drive is an LVM, + don't append the RAID prefix afterwards. + Reported by Clint Adams. + +2008-06-08 Robert Millan + + Based on description from Pavel: + * kern/disk.c (grub_disk_check_range): Rename to ... + (grub_disk_adjust_range): ... this. Add a comment explaining the + tasks performed by this function. + +2008-06-08 Robert Millan + + * include/grub/ntfs.h (struct grub_ntfs_bpb): Rename `serial_number' to + `num_serial' (for consistency with other variables). + (struct grub_ntfs_data): Add `uuid' member. + * fs/ntfs.c (grub_ntfs_mount): Initialize `data->uuid'. + (grub_ntfs_uuid): New function. + (grub_ntfs_fs): Reference grub_ntfs_uuid() in `uuid' struct member. + +2008-06-07 Pavel Roskin + + * util/biosdisk.c (open_device): Revert last change to the + function, it broke installation. The sector needs to be + different dependent on which device is opened. + +2008-06-06 Robert Millan + + Ensure GRUB_KERNEL_MACHINE_DATA_END is always consistent with the + rest of GRUB, and breakage doesn't happen if its value were modified. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Redefine as an offset from `GRUB_KERNEL_MACHINE_DATA_END' instead of + a constant (same value). + * kern/i386/pc/startup.S: Replace hardcoded `0x50' with + `GRUB_KERNEL_MACHINE_DATA_END' (same value). + +2008-06-06 Robert Millan + + * util/biosdisk.c (open_device): Do not modify sector offset when + accessing a partition. kern/disk.c already handles this for us. + +2008-06-06 Robert Millan + + * util/grub-emu.c (grub_machine_init): Move code in this function from + here ... + (main): ... to here (before grub_util_biosdisk_init() call, to prevent + segfault in case grub_printf() is called). + + * util/i386/pc/grub-install.in: Append `--device-map=${device_map}' to + grub_probe. Update all users not to explicitly add it again. + (grub_device): New variable; contains corresponding device for grubdir. + (fs_module, partmap_module, devabstraction_module): Pass + `--device ${grub_device}' to grub_probe to avoid traversing /dev + every time. + +2008-06-05 Robert Millan + + * normal/misc.c (grub_normal_print_device_info): When a filesystem UUID + is found, print it (same layout as with labels). + +2008-06-04 Robert Millan + + * util/biosdisk.c (get_drive): Rename to ... + (find_grub_drive): ... this. Update all users. + + (get_os_disk): Rename to ... + (convert_system_partition_to_system_disk): ... this. Update all users. + + (find_drive): Rename to ... + (find_system_device): ... this. Update all users. + +2008-06-04 Robert Millan + + * util/biosdisk.c (get_os_disk): Handle IDA devices. + * util/grub-mkdevicemap.c (get_mmc_disk_name) + (make_device_map): Likewise. + +2008-06-01 Robert Millan + + * util/biosdisk.c (get_drive): Verify that `map[i].drive' is non-NULL + before dereferencing it. + + * fs/fat.c (struct grub_fat_bpb): Move fat32-specific fields into a + union with fat12/fat16-specific ones. Add some new fields, including + `num_serial' for both versions. + (struct grub_fat_data): Add `uuid' member. + (grub_fat_mount): Refer to fat32-specific fields in `bpb' by their new + names. Initialize `data->uuid' using `num_serial'. + (grub_fat_uuid): New function. + (grub_fat_fs): Reference grub_fat_uuid() in `uuid' struct member. + + * fs/reiserfs.c (grub_reiserfs_superblock): Add `uuid' field. + (grub_reiserfs_uuid): New function. + (grub_reiserfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct + member. + + * fs/xfs.c (grub_xfs_sblock): Add `uuid' field. + (grub_xfs_uuid): New function. + (grub_xfs_fs): Reference grub_reiserfs_uuid() in `uuid' struct member. + +2008-06-01 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): Generate + code that is backward compatible with pre-uuid search command. + +2008-05-31 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Iterate through + floppies after everything else, to ensure floppy drive isn't accessed + unnecessarily (patch from Bean). + +2008-05-31 Robert Millan + + * commands/search.c (search_label, search_fs_uuid, search_file): Do + not print device names when we were asked to set a variable. + +2008-05-31 Robert Millan + + * term/ieee1275/ofconsole.c (grub_ofconsole_setcursor): Implement + using "cursor-on" and "cursor-off" commands (understood at least by + the Open Firmware flavour on OLPC). + +2008-05-31 Michael Gorven + + * term/terminfo.c (grub_terminfo_set_current): Correct vt100 cursor + on and off sequences. + +2008-05-31 Robert Millan + + * util/update-grub_lib.in: Replace `grub-probe' with `${grub_probe}'. + * util/update-grub.in: Likewise. + +2008-05-30 Pavel Roskin + + * util/biosdisk.c (linux_find_partition): Simplify logic and + make the code more universal. Keep special processing for + devfs, but use a simple rule for all other devices. If the + device ends with a number, append 'p' and the partition number. + Otherwise, append only the partition number. + +2008-05-30 Robert Millan + + * util/update-grub.in (GRUB_DISABLE_LINUX_UUID): Export variable. + * util/grub.d/10_linux.in: If GRUB_DEVICE_UUID is set, and + GRUB_DISABLE_LINUX_UUID isn't true, use the filesystem UUIDs as + the `root' parameter to Linux. + +2008-05-30 Robert Millan + + * commands/search.c (options): Rename --fs_uuid to --fs-uuid. + * util/update-grub_lib.in (prepare_grub_to_access_device): Replace + --fs_uuid with --fs-uuid. + * util/update-grub.in: Allow filesystem UUID probes to fail (since not + all filesystems support them). + +2008-05-30 Robert Millan + + * fs/ext2.c (grub_ext2_uuid): Use `04x' instead of '02x' as + grub_printf() flags, since we're printing in units of 2 bytes. + +2008-05-30 Robert Millan + + * util/grub.d/00_header.in: Remove obsolete comment referencing + convert_system_path_to_grub_path(). + * util/update-grub.in: Likewise. + * util/update-grub_lib.in (is_path_readable_by_grub): New function. + (convert_system_path_to_grub_path): Add a warning message explaining + that this function is deprecated. Rely on is_path_readable_by_grub() + for the readability checks. + (font_path): Use is_path_readable_by_grub() for the readability + check rather than convert_system_path_to_grub_path(). + +2008-05-30 Robert Millan + + * util/update-grub_lib.in (prepare_grub_to_access_device): New function. + * util/update-grub.in: Set `GRUB_FONT_PATH' to the system path, without + converting it first. + * util/grub.d/00_header.in: Use prepare_grub_to_access_device() to setup + grub.cfg for access to font file, and afterwards call it again to set + the root device. + +2008-05-30 Robert Millan + + * commands/search.c (options): Add --fs_uuid option. + (search_fs_uuid): New function. + (grub_cmd_search): Fix --set argument passing. + Use search_fs_uuid() when requested via --fs_uuid. + (grub_search_init): Update help message. + * fs/ext2.c (struct grub_ext2_sblock): Rename `unique_id' to `uuid' + and redeclare it as an array of 16-bit words. + (grub_ext2_uuid): New function. + (grub_ext2_fs): Reference grub_ext2_uuid() in `uuid' struct member. + * include/grub/fs.h (struct grub_fs): Add `uuid' struct member. + * util/update-grub.in (GRUB_DEVICE_UUID, GRUB_DEVICE_BOOT) + (GRUB_DEVICE_BOOT_UUID): New variables. + (GRUB_DRIVE. GRUB_DRIVE_BOOT. GRUB_DRIVE_BOOT_GRUB): Remove. + * util/grub.d/00_header.in: Set root using `search --fs_uuid' command + whenever possible. + * util/grub.d/10_hurd.in: Avoid explicit use of root drive. Instead, + just assume `root' variable has the right value. + * util/grub.d/10_linux.in: Likewise. + * util/grub-probe.c (probe): Probe for filesystem UUID when requested + via PRINT_FS_UUID. + (main): Recognise `-t fs_uuid' argument. + +2008-05-30 Robert Millan + + * util/biosdisk.c (map): Redefine structure to hold information + about GRUB drive name. + (get_drive): Reimplement without assuming (and verifying) BIOS-like + drive names. + (call_hook): Remove. + (grub_util_biosdisk_iterate): Access drive names via `.drive' struct + member. Assume drive has partitions. + (grub_util_biosdisk_open): Access device names via `.device' struct + member. + (open_device): Likewise. + (find_drive): Likewise. + (read_device_map): Adjust map[] usage to match the new struct + definition. Don't check for duplicates (still possible, but not cheap + anymore). + (grub_util_biosdisk_fini): Free malloced buffers referenced by map[]. + (make_device_name): Remove assumption of BIOS-like drive names. + +2008-05-30 Pavel Roskin + + * conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Remove, as + compiling execute.c doesn't need grub_script.tab.h anymore. + (normal/command.c_DEPENDENCIES): Likewise. + (normal/function.c_DEPENDENCIES): Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + +2008-05-29 Pavel Roskin + + * disk/lvm.c (grub_lvm_scan_device): Check for the buffer end + when scanning metadata for volume group name. + + * include/grub/script.h: Don't include grub_script.tab.h. It's + a generated file, which may only be included from the files with + DEPENDENCIES rules in the makefile. Don't use typedef YYSTYPE, + use union YYSTYPE, as the later allows forward declaration. + * normal/lexer.c: Don't use typedef YYSTYPE, use union YYSTYPE. + +2008-05-29 Robert Millan + + * term/i386/pc/at_keyboard.c: Include `grub/machine/machine.h'. + (OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT): New macros. + [GRUB_MACHINE_IEEE1275] (keyboard_map): Add OLPC scan codes + (grub_console_checkkey): Add grub_dprintf() call to report unknown + scan codes. + +2008-05-29 Robert Millan + + * term/i386/pc/at_keyboard.c (grub_console_checkkey): Add support for + control key combinations. + +2008-05-29 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Move from here ... + * util/ieee1275/grub-install.in: ... to here. + * powerpc-ieee1275.rmk (grub_install_SOURCES): Update location. + * i386-ieee1275.rmk (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): Likewise. + +2008-05-29 Robert Millan + + * fs/affs.c: Update copyright year. + * fs/ext2.c: Likewise. + * fs/fshelp.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/xfs.c: Likewise. + * include/grub/fshelp.h: Likewise. + * util/grub-mkdevicemap.c: Likewise. + +2008-05-28 Robert Millan + + * util/update-grub.in: Allow chmod call to fail, since /boot/grub/ + might need to be fatfs to support some firmware implementations + (e.g. OFW or EFI). + +2008-05-28 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle MMC + devices. + * util/grub-mkdevicemap.c (get_mmc_disk_name) + (make_device_map): Likewise. + +2008-05-20 Bean + + * fs/fshelp.c (grub_fshelp_map_block): New function. + (grub_fshelp_find_file): Use 64-bit type for pos and block address. + Use `>>' and `&' operator to avoid 64-bit divide and modulo. + + * include/grub/fshelp.h (grub_fshelp_journal_type): New enum. + (GRUB_FSHELP_JOURNAL_UNUSED_MAPPING): New macro. + (grub_fshelp_journal): New structure. + (grub_fshelp_map_block): New function prototype. + (grub_fshelp_read_file): Use grub_disk_addr_t as block type. + (grub_fshelp_map_block): Likewise. + + * fs/ext2.c (EXT3_FEATURE_COMPAT_HAS_JOURNAL): New macro. + (EXT3_JOURNAL_MAGIC_NUMBER): Likewise. + (EXT3_JOURNAL_DESCRIPTOR_BLOCK): Likewise. + (EXT3_JOURNAL_COMMIT_BLOCK): Likewise. + (EXT3_JOURNAL_SUPERBLOCK_V1): Likewise. + (EXT3_JOURNAL_SUPERBLOCK_V2): Likewise. + (EXT3_JOURNAL_REVOKE_BLOCK): Likewise. + (EXT3_JOURNAL_FLAG_ESCAPE): Likewise. + (EXT3_JOURNAL_FLAG_SAME_UUID): Likewise. + (EXT3_JOURNAL_FLAG_DELETED): Likewise. + (EXT3_JOURNAL_FLAG_LAST_TAG): Likewise. + (grub_ext2_sblock): New members for journal support. + (grub_ext3_journal_header): New structure. + (grub_ext3_journal_revoke_header): Likewise. + (grub_ext3_journal_block_tag): Likewise. + (grub_ext3_journal_sblock): Likewise. + (grub_fshelp_node): New members logfile and journal. + (grub_ext2_read_block): Change block type to grub_disk_addr_t. Use + grub_fshelp_map_block to get real block number. + (grub_ext2_blockgroup): Use grub_fshelp_map_block to get real block + number. + (grub_ext2_read_inode): Likewise. + (grub_ext3_get_journal): New function. + (grub_read_inode): Initialize journal using grub_ext3_get_journal. + (grub_ext2_close): Release memory used by journal. + + * fs/reiserfs.c (REISERFS_MAGIC_STRING): Changed to "ReIsEr". + (REISERFS_MAGIC_DESC_BLOCK): New macro. + (grub_reiserfs_transaction_header): Renamed to + grub_reiserfs_description_block, replace field data with real_blocks. + (grub_reiserfs_commit_block): New structure. + (grub_reiserfs_data): New member journal. + (grub_reiserfs_get_item): Use grub_fshelp_map_block to get real block + number. + (grub_reiserfs_read_symlink): Likewise. + (grub_reiserfs_iterate_dir): Likewise. + (grub_reiserfs_open): Likewise. + (grub_reiserfs_read): Likewise. + (grub_reiserfs_get_journal): New function. + (grub_reiserfs_mount): Use "ReIsEr" as super block magic, as there are + three varieties ReIsErFs, ReIsEr2Fs and ReIsEr3Fs. Initialize journal + using grub_reiserfs_get_journal. + (grub_reiserfs_close): Release memory used by journal. + + * fs/affs.c (grub_affs_read_block): Change block type to + grub_disk_addr_t. Use grub_divmod64 to do 64-bit division. + + * fs/afs.c (grub_afs_read_block): Change block type to grub_disk_addr_t. + + * fs/hfsplus.c (grub_hfsplus_read_block): Likewise. + + * fs/ntfs.c (grub_ntfs_read_block): Likewise. + + * fs/udf.c (grub_udf_read_block): Change block type to + grub_disk_addr_t. Use type cast to avoid warning. + + * fs/xfs.c (grub_xfs_read_block): Likewise. + +2008-05-16 Christian Franke + + * commands/cat.c (grub_cmd_cat): Remove non-ESC keys from keyboard queue + to ensure that break with ESC will always work. + * commands/sleep.c (grub_interruptible_millisleep): Likewise. + Remove ESC from keyboard queue. + +2008-05-16 Christian Franke + + * util/biosdisk.c: [__CYGWIN__] Add includes. + (grub_util_biosdisk_open): Use Linux code also for Cygwin. + (get_os_disk): Move variable declarations to OS specific + parts to avoid warning. + [__GNU__] (get_os_disk): Fix /dev/sdXsN case. + [__CYGWIN__] (get_os_disk): Add Cygwin /dev/sdXN device names. + (grub_util_biosdisk_get_grub_dev): Use Linux code also for + Cygwin. + * util/getroot.c: [__CYGWIN__] Add includes. + (strip_extra_slashes): Fix "/" case. + [__CYGWIN__] (get_win32_path): New function. + [__CYGWIN__] (grub_get_prefix): Add conversion to win32 path. + [__CYGWIN__] (find_root_device): Disable. + [__CYGWIN__] (get_bootsec_serial): New function. + [__CYGWIN__] (find_cygwin_root_device): Likewise. + [__linux__] (grub_guess_root_device): Add early returns to simplify + structure. + [__CYGWIN__] (grub_guess_root_device): Call find_cygwin_root_device. + [__linux__] (grub_util_get_dev_abstraction): Enable LVM and RAID + check for Linux only. + +2008-05-15 Bean + + * kern/i386/pc/startup.S (grub_console_getkey): Workaround for the + keyboard hang problem in apple's intel mac. + +2008-05-09 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle Virtio + devices. + * util/grub-mkdevicemap.c (get_virtio_disk_name) + (make_device_map): Likewise. + Reported by Aurelien Jarno + +2008-05-07 Ian Campbell + + * util/biosdisk.c (get_os_disk): Recognise xvd type disks. + * util/grub-mkdevicemap.c (get_xvd_disk_name): New function. + (make_device_map): Output entries for xvd type disks. + +2008-05-07 Robert Millan + + * util/biosdisk.c (linux_find_partition, get_os_disk): Handle CCISS + devices. + * util/grub-mkdevicemap.c (get_cciss_disk_name) + (make_device_map): Likewise. + Reported by Roland Dreier + +2008-05-07 Robert Millan + + * disk/lvm.c (grub_lvm_scan_device): Detect errors in an additional + grub_strstr() call. Correct a few mistakes in failure path handling. + +2008-05-06 Robert Millan + + * util/update-grub_lib.in (make_system_path_relative_to_its_root): + Do not print a trailing slash (therefore, the root directory is an + empty string). + (convert_system_path_to_grub_path): Do not remove trailing slash + from make_system_path_relative_to_its_root() output. + + * util/i386/pc/grub-install.in: Add trailing slash to output from + make_system_path_relative_to_its_root(). + +2008-05-06 Robert Millan + + * util/grub-fstest.c (grub_refresh): Call `fflush (stdout)'. This + ensures that output lines aren't intermangled with those sent to + stderr (via grub_util_info()). + * util/grub-probe.c (grub_refresh): Likewise. + * util/i386/pc/grub-setup.c (grub_refresh): Likewise. + +2008-05-05 Christian Franke + + * util/grub-mkdevicemap.c (get_floppy_disk_name) [__CYGWIN__]: + Add Cygwin device names. + (get_ide_disk_name) [__CYGWIN__]: Likewise. + (get_scsi_disk_name) [__CYGWIN__]: Likewise. + (check_device): Return error instead of success on empty name. + (make_device_map): Move label inside linux specific code to + prevent compiler warning. + +2008-04-30 Robert Millan + + Based on patch from Fabian Greffrath + * util/grub.d/10_linux.in: Add ${GRUB_CMDLINE_LINUX_DEFAULT} to the + first boot option. + * util/update-grub.in: Export GRUB_CMDLINE_LINUX_DEFAULT. + +2008-04-29 Robert Millan + + * docs/grub.cfg: New file (example GRUB configuration). + +2008-04-26 Robert Millan + + * DISTLIST: Sort (sort -u < DISTLIST | sponge DISTLIST). Add + `loader/i386/ieee1275/linux.c', `loader/i386/ieee1275/linux_normal.c' + and `disk/ieee1275/nand.c'. + +2008-04-25 Bean + + * Makefile.in (RMKFILES): Add missing arch i386-ieee1275 and + i386-linuxbios. + + * commands/hexdump.c (grub_cmd_hexdump): Support dumping of device, + change the buffer size to 4096 for cdrom device. + + * conf/i386-ieee1275.rmk (pkglib_MODULES): Add _linux.mod, linux.mod + and nand.mod. + (_linux_mod_SOURCES): New variable. + (_linux_mod_CFLAGS): Likewise. + (_linux_mod_LDFLAGS): Likewise. + (linux_mod_SOURCES): Likewise. + (linux_mod_CFLAGS): Likewise. + (linux_mod_LDFLAGS): Likewise. + (nand_mod_SOURCES): Likewise. + (nand_mod_CFLAGS): Likewise. + (nand_mod_LDFLAGS): Likewise. + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Return + GRUB_ERR_UNKNOWN_DEVICE instead of GRUB_ERR_BAD_DEVICE if no device + type property. (nand device in olpc don't have this property) + + * include/grub/disk.h (grub_disk_dev_id): New macro + GRUB_DISK_DEVICE_NAND_ID. + + * include/grub/i386/ieee1275/loader.h (grub_rescue_cmd_linux): New + function prototype. + (grub_rescue_cmd_initrd): Likewise. + + * include/grub/i386/linux.h (GRUB_LINUX_OFW_SIGNATURE): New macro. + (linux_kernel_params): Add new member ofw_signature, ofw_num_items, + ofw_cif_handler and ofw_idt, adjust padding number. + + * include/grub/i386/pc/memory.h (grub_upper_mem): Export it if + GRUB_MACHINE_IEEE1275 is defined. + + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): + Use NESTED_FUNC_ATTR attribute on the hook parameter. + + * kern/powerpc/ieee1275/init.c (grub_claim_heap): Use NESTED_FUNC_ATTR + on nested function heap_init. + (grub_upper_mem): New variable for i386-ieee1275. + (grub_get_extended_memory): New function for i386-ieee1275. + (grub_machine_init): Call grub_get_extended_memory for i386-ieee1275. + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Use + NESTED_FUNC_ATTR on the hook parameter. Don't quit if no device type + property. + + * loader/i386/ieee1275/linux.c: New file. + + * loader/i386/ieee1275/linux_normal.c: New file. + + * disk/ieee1275/nand.c: New file. + +2008-04-18 Thomas Schwinge + + * util/i386/pc/grub-mkrescue.in (grub_mkimage): Don't overwrite correct + value. + * util/powerpc/ieee1275/grub-mkrescue.in (grub_mkimage): Likewise. + +2008-04-18 Robert Millan + + Restructures early code path on ieee1275 to unify grub_main() as + the first C function that is executed in every platform. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_init): New prototype. + * kern/i386/ieee1275/startup.S (_start): Jump to grub_main() instead of + cmain(). + * kern/powerpc/ieee1275/crt0.S (_start): Likewise. + * kern/ieee1275/cmain.c (cmain): Rename to ... + * kern/ieee1275/cmain.c (grub_ieee1275_init): ... this. + * kern/ieee1275/init.c (grub_machine_init): Call grub_ieee1275_init() + at the beginning. + +2008-04-18 Robert Millan + + * util/update-grub.in: Fix syntax error when setting + `GRUB_PRELOAD_MODULES'. + Reported by Stephane Chazelas + +2008-04-17 Lubomir Kundrak + + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): take only .text + section into account, newer toolchains generate unique build ids + * configure.ac: remove the test for --build-id=none acceptance, + we want build ids to be preserved + * genmk.rb: add -R .note.gnu.build-id to objcopy, so build id + far from other sections don't cause the raw binary images grow + size + +2008-04-15 Robert Millan + + * disk/lvm.c: Update copyright year. + * kern/misc.c: Likewise. + +2008-04-14 Vesa Jaaskelainen + + * disk/lvm.c (grub_lvm_scan_device): Add forgotten failure path when + there is no memory left for physical volume name. + +2008-04-14 Vesa Jaaskelainen + + * disk/lvm.c (grub_lvm_scan_device): Fix logical volume's physical + volume name mapping to support bigger than 9 character names properly. + +2008-04-13 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_rw): Fix CHS limit check, + as per http://www.allensmith.net/Storage/HDDlimit/Int13h.htm + +2008-04-13 Christian Franke + + * util/i386/pc/grub-mkrescue.in: Add --emulation=floppy + to create a floppy emulation boot CD when non emulation mode + does not work. + Enable Joliet CD filesystem extension. + +2008-04-13 Robert Millan + + * kern/misc.c (grub_strncat): Fix off-by-one error. + Reported by Zhang Huan + + * kern/env.c (grub_env_context_close): Clear current context, not + previous one. + Patch from Zhang Huan + + * kern/misc.c (grub_strcat): Minor speed optimization (same code size). + +2008-04-13 Robert Millan + + Improve robustness when handling LVM. + + * disk/lvm.c (grub_lvm_getvalue): Return 0 when `*p' is NULL + (and leave `*p' unmodified). + (grub_lvm_iterate): Don't assume `vg->lvs != NULL' when iterating + through it. + (grub_lvm_memberlist): Don't assume `lv->vg->pvs != NULL' when + iterating through it. + (grub_lvm_open): Don't assume `vg->lvs != NULL' when iterating + through it. + (grub_lvm_scan_device): Check the return value (and fail gracefully + when due) on each grub_lvm_getvalue() or grub_strstr() call. + Don't assume `vg->pvs != NULL' when iterating through it. + +2008-04-13 Robert Millan + + * gendistlist.sh (EXTRA_DISTFILES): Add `genpartmaplist.sh'. + * genmk.rb (partmap): New variable. + (CLEANFILES, PARTMAPFILES): Add #{partmap}. + (#{partmap}): New target rule. + * genpartmaplist.sh: New file. + * Makefile.in (pkglib_DATA): Add partmap.lst. + (partmap.lst): New target rule. + * util/i386/pc/grub-mkrescue.in: Generate grub.cfg that loads needed + modules (including all partition maps), instead of preloading them. + +2007-04-13 Fabian Greffrath + + * util/grub.d/30_os-prober.in: New script. Use `os-prober' and + `linux-boot-prober' (if installed) to detect other operating + systems which are installed on the computer and add them to + the boot menu. + * conf/common.rmk: Build and install 30_os-prober. + +2008-04-12 Robert Millan + + * kern/powerpc/ieee1275/init.c: Move from here ... + * kern/ieee1275/init.c: ... to here. Update all users. + + * kern/powerpc/ieee1275/cmain.c: Move from here ... + * kern/ieee1275/cmain.c: ... to here. Update all users. + + * kern/powerpc/ieee1275/openfw.c: Move from here ... + * kern/ieee1275/openfw.c: ... to here. Update all users. + + * loader/powerpc/ieee1275/multiboot2.c: Move from here ... + * loader/ieee1275/multiboot2.c: ... to here. Update all users. + +2008-04-10 Pavel Roskin + + * configure.ac: Always use "_cv_" in cache variables for + compatibility with Autoconf 2.62. + +2008-04-07 Robert Millan + + Revert grub/machine/init.h addition by Pavel (since it breaks on + i386-ieee1275 and others): + * util/i386/pc/misc.c: Remove grub/machine/init.h. + * util/powerpc/ieee1275/misc.c: Likewise. + +2008-04-07 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + +2008-04-07 Robert Millan + + * util/biosdisk.c (read_device_map): Skip devices that don't exist + (this prevents the presence of a bogus entry from ruining the whole + thing). + +2008-04-06 Pavel Roskin + + * util/biosdisk.c: Include grub/util/biosdisk.h. + * util/grub-fstest.c (execute_command): Make static. + * util/grub-mkdevicemap.c (check_device): Likewise. + * util/i386/pc/misc.c: Include grub/machine/init.h. + * util/powerpc/ieee1275/misc.c: Likewise. + * util/lvm.c: Include grub/util/lvm.h. + * util/misc.c: Include grub/kernel.h, grub/misc.h and + grub/cache.h. + * util/raid.c: Include grub/util/raid.h. + (grub_util_getdiskname): Make static. + + * util/grub-emu.c (main): Remove calls to grub_hostfs_init() and + grub_hostfs_fini(), as they are called from grub_init_all() and + grub_fini_all() respectively. This fixes an infinite loop in + grub-fstest due to double registration of hostfs. + Reported by Christian Franke + +2008-04-05 Pavel Roskin + + * bus/pci.c (grub_pci_iterate): For multifunction devices, probe + all 8 functions. Otherwise, probe function 0 only. + +2008-04-04 Pavel Roskin + + * commands/lspci.c (grub_lspci_iter): Print the bus number + correctly. + + * commands/lspci.c (grub_pci_classes): Fix typos. + (grub_lspci_iter): Don't print func twice. Print vendor ID + before device ID, as it's normally done. + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): + Fix signedness warnings. + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): + Likewise. + * util/ieee1275/get_disk_name.c: Include config.h so that + _GNU_SOURCE is defined and getline() is declared. Mark an + unused argument as such. Fix a signedness warning. + +2008-04-02 Pavel Roskin + + * genkernsyms.sh.in: Use more robust assignments for CC and + srcdir. Quote srcdir. + * gensymlist.sh.in: Likewise. Assert at the compile time that + the symbol table is not empty. + + * disk/raid.c (grub_raid_memberlist): Fix a signedness warning. + * fs/cpio.c (grub_cpio_read): Likewise. + +2008-04-01 Pavel Roskin + + * disk/ata.c (grub_ata_open): Don't lose precision in disk->id. + * disk/host.c (grub_host_open): Likewise. + * disk/loopback.c (grub_loopback_open): Likewise. + * disk/memdisk.c (grub_memdisk_open): Use a string pointer for + disk->id as in disk/host.c, not a multi-character constant. + + * util/grub-fstest.c (cmd_cmp): Use fseeko(), not fseek(). The + later is obsolete, potentially dangerous and sets a bad example. + * util/i386/efi/grub-mkimage.c (make_header): Likewise. + * util/misc.c (grub_util_get_image_size): Likewise. + + * disk/loopback.c (options): Improve help for "--partitions". + + * normal/arg.c (grub_arg_show_help): Fix spacing of the long + options to align them with the short options, e.g. "echo -e". + +2008-03-31 Bean + + * video/reader/png.c (grub_png_data): New member is_16bit and + image_data. + (grub_png_decode_image_header): Detect 16 bit png image. + (grub_png_convert_image): New function to convert 16 bit image to 8 bit. + (grub_png_decode_png): Call grub_png_convert_image for 16 bit image. + (grub_video_reader_png): Release memory occupied by image_data. + + * fs/ntfs.c (find_attr): Handle non-resident attribute list larger than + 4096 bytes. + (grub_nfs_mount): Skip the test for sector per cluster. + + * include/grub/ntfs.h (MAX_SPC): Removed. + +2008-03-31 Bean + + * conf/common.rmk (pkgdata_MODULES): Add afs.mod. + (grub_probe_SOURCES): Add fs/afs.c. + (grub_fstest_SOURCES): Likewise. + (afs_mod_SOURCES): New variable. + (afs_mod_CFLAGS): Likewise. + (afs_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/afs.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/afs.c: New file. + +2008-03-30 Pavel Roskin + + * disk/host.c: Include grub/misc.h to fix a warning. + * util/hostfs.c: Use GRUB_MOD_INIT and GRUB_MOD_FINI to fix + warnings about implicit declarations. + + * fs/udf.c (grub_udf_mount): Fix warning about a shadowing a + variable. + * include/grub/i386/loader.h: Change declaration of + grub_linux_boot() to match what grub_loader_set() expects. + * util/getroot.c (grub_guess_root_device): Return const char* to + fix a warning. + * util/grub-probe.c (probe): Fix a warning about uninitialized + abstraction_name variable. + * util/i386/get_disk_name.c (grub_util_get_disk_name): Mark + second argument as unused to fix a warning. + + * loader/i386/pc/multiboot2.c (grub_mb2_arch_elf64_hook): Add + missing grub_error() call. + + * util/update-grub_lib.in: Define datarootdir, since Autoconf + 2.60 and newer uses it to define datadir. + + * commands/sleep.c: Fix warning about implicit declaration. + * disk/memdisk.c: Likewise. + * loader/aout.c: Likewise. + * loader/i386/bsd_normal.c: Likewise. + * util/grub-probe.c: Likewise. + + * commands/i386/cpuid.c (has_longmode): Make static. + * disk/i386/pc/biosdisk.c (cd_drive): Likewise. + * include/grub/i386/bsd.h (bios_memmap_t): Remove, it's unused. + + * kern/i386/pc/startup.S (real_to_prot): Use %cs prefix to load + GDT. This is more robust, as %ds can change. + (grub_biosdisk_rw_int13_extensions): Don't clear %ds before + calling real_to_prot(). + (grub_biosdisk_get_diskinfo_int13_extensions): Likewise. + +2008-03-28 Pavel Roskin + + * kern/i386/pc/startup.S: Assert that uncompressed functions + don't spill beyond GRUB_KERNEL_MACHINE_RAW_SIZE. + * kern/i386/pc/lzo1x.S: Remove all .align directives in the + code, as they push parts of the code (error handlers) beyond + GRUB_KERNEL_MACHINE_RAW_SIZE. Speed is not as important in this + code as correctness and size. + +2008-03-28 Pavel Roskin + + * kern/i386/pc/startup.S + (grub_biosdisk_get_diskinfo_int13_extensions): When converting + data block address to the real mode, keep offset minimal. This + works around a bug in AWARD BIOS on old Athlon systems, which + makes CD detection hang. + +2008-03-26 Pavel Roskin + + * normal/color.c (grub_parse_color_name_pair): Make `name' a + const. + * include/grub/normal.h: Add grub_parse_color_name_pair() + declaration. + +2008-03-24 Bean + + * disk/i386/pc/biosdisk.c (cd_start): Removed. + (cd_count): Removed. + (cd_drive): New variable. + (grub_biosdisk_get_drive): Don't check for (cdN) device. + (grub_biosdisk_call_hook): Likewise. + (grub_biosdisk_iterate): Change cdrom detection method. + (grub_biosdisk_open): Replace cd_start with cd_drive. + (GRUB_MOD_INIT): Use grub_biosdisk_get_cdinfo_int13_extension to + detect cdrom device. + + * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_MACHINE_CDROM_START): + Removed. + (GRUB_BIOSDISK_MACHINE_CDROM_END): Removed. + (GRUB_BIOSDISK_CDTYPE_NO_EMUL): New macro. + (GRUB_BIOSDISK_CDTYPE_1_2_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_1_44_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_2_88_M): Likewise. + (GRUB_BIOSDISK_CDTYPE_HARDDISK): Likewise. + (GRUB_BIOSDISK_CDTYPE_MASK): Likewise. + (grub_biosdisk_cdrp): New structure. + (grub_biosdisk_get_cdinfo_int13_extensions): New function. + + * include/grub/i386/pc/kernel.h (grub_boot_drive): Export this variable. + + * kern/i386/pc/init.c (make_install_device): Don't use (cdN) as root + device. + + * kern/i386/pc/startup.S (grub_biosdisk_get_cdinfo_int13_extensions): + New function. + +2008-03-20 Robert Millan + + Remove 2 TiB limit in ata.mod. + * disk/ata.c (grub_ata_device): Promote `size' to grub_uint64_t. + (grub_ata_dumpinfo): Print sector count with 0x%llx. + (grub_ata_identify): Interpret `&info16[100]' as a pointer to + grub_uint64_t instead of grub_uint32_t. + +2008-03-05 Bean + + * loader/i386/pc/multiboot.c (grub_multiboot_get_bootdev): New function. + (grub_multiboot): Set boot device. + + * boot/i386/pc/lnxboot.S (real_code_2): Set %dh to 0xFF. + +2008-03-02 Bean + + * fs/reiserfs.c (grub_reiserfs_read_symlink): Add 0 at the end of + symlink_buffer. + +2008-03-01 Yoshinori K. Okuji + + * DISTLIST: Added docs/fdl.texi, docs/grub.texi, docs/mdate-sh and + texinfo.tex. + + * docs/grub.texi: New file. Copied from GRUB Legacy, and slightly + modified. + + * docs/fdl.texi: New file. + + * docs/mdate-sh: New file. Copied from gnulib. + * docs/texinfo.tex: Likewise. + + * config.guess: Updated from gnulib. + * install-sh: Likewise. + +2008-02-28 Robert Millan + + * conf/i386-linuxbios.rmk (pkglib_MODULES): Add aout.mod. + (aout_mod_SOURCES): New variable. + (aout_mod_CFLAGS): Likewise. + (aout_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk: Likewise. + +2008-02-28 Robert Millan + + * util/update-grub.in: Reorganise terminal validity check. Accept + `ieee1275:console' (OLPC) and `*:gfxterm' as valid too. + Based on suggestion by Franklin PIAT. + +2008-02-28 Fabian Greffrath + + * include/grub/util/getroot.h (grub_util_check_block_device): Export new + function. + * util/getroot.c (grub_util_check_block_device): New function that + returns the given argument if it is a block device and returns NULL else. + * util/grub-probe.c (argument_is_device): New variable. + (probe): Promote device_name from a variable to an argument. Receive + device_name from grub_util_check_block_device() if path is NULL and from + grub_guess_root_device() else. Do not free() device_name anymore. + (options): Introduce new parameter '-d, --device'. + (main): Add description of the new parameter to the help screen. + Rename path variable to argument. Set argument_is_device if the '-d' + option is given. Pass argument to probe() depending on + argument_is_device. + +2008-02-24 Bean + + * fs/iso9660.c (GRUB_ISO9660_VOLDESC_BOOT): New macro. + (GRUB_ISO9660_VOLDESC_PRIMARY): Likewise. + (GRUB_ISO9660_VOLDESC_SUPP): Likewise. + (GRUB_ISO9660_VOLDESC_PART): Likewise. + (GRUB_ISO9660_VOLDESC_END): Likewise. + (grub_iso9660_primary_voldesc): New member escape. + (grub_iso9660_data): New member joliet. + (grub_iso9660_convert_string): New function. + (grub_iso9660_mount): Detect joliet extension. + (grub_iso9660_iterate_dir): Convert filename when joliet is detected. + (grub_iso9660_iso9660_label): Likewise. + + * conf/common.rmk (pkgdata_MODULES): Add udf.mod. + (grub_setup_SOURCES): Add fs/udf.c. + (grub_fstest_SOURCES): Likewise. + (udf_mod_SOURCES): New variable. + (udf_mod_CFLAGS): Likewise. + (udf_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/udf.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/udf.c: New file. + +2008-02-24 Robert Millan + + * conf/i386-efi.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): New variables. + * conf/i386-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/i386-linuxbios.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/i386-pc.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/powerpc-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + * conf/sparc64-ieee1275.rmk (normal/function.c_DEPENDENCIES) + (normal/lexer.c_DEPENDENCIES): Likewise. + +2008-02-23 Robert Millan + + * partmap/gpt.c (grub_gpt_magic): Add `0x' qualifier to each member, + since they were intended to be in hex. This didn't break previously + because of a bug in gpt_partition_map_iterate() (see below). + + (gpt_partition_map_iterate): Replace `grub_memcmp' with `! grub_memcmp' + when checking the validity of GPT header. + Remove `partno', since it always provides the same information as `i'. + +2008-02-21 Yoshinori K. Okuji + + * include/grub/efi/time.h: Fix a wrong comment. + +2008-02-19 Pavel Roskin + + * kern/rescue.c (grub_enter_rescue_mode): Improve initial + message. + +2008-02-19 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add aout.mod _bsd.mod and bsd.mod. + (aout_mod_SOURCES): New variable. + (aout_mod_CFLAGS): Likewise. + (aout_mod_LDFLAGS): Likewise. + (_bsd_mod_SOURCES): New variable. + (_bsd_mod_CFLAGS): Likewise. + (_bsd_mod_LDFLAGS): Likewise. + (bsd_mod_SOURCES): New variable. + (bsd_mod_CFLAGS): Likewise. + (bsd_mod_LDFLAGS): Likewise. + + * include/grub/aout.h: New file. + + * include/grub/i386/loader.h (grub_unix_real_boot): New function. + + * include/grub/i386/bsd.h: New file. + + * include/grub/i386/pc/init.h (grub_get_mmap_entry): Use EXPORT_FUNC + to make it public. + + * kern/elf.c (grub_elf32_load): Get the physical address after the hook + function is called, so that it's possible to change it inside the hook. + (grub_elf64_load): Likewise. + (grub_elf_file): Don't close the file if elf header is not found. + (grub_elf_close): Close the file if grub_elf_file fails (The new + grub_elf_file won't close it). + (grub_elf32_size): Use NESTED_FUNC_ATTR for nested function calcsize. + (grub_elf64_size): Likewise. + + * kern/i386/loader.S (grub_unix_real_boot): New function. + + * loader/aout.c: New file. + + * loader/i386/bsd.c: New file. + + * loader/i386/bsd_normal.c: New file. + + * loader/i386/pc/multiboot.c (grub_multiboot): Handle a.out format. + + * loader/multiboot2.c (grub_multiboot2): Reset grub_errno so that it + can test other formats. + +2008-02-19 Robert Millan + + * partmap/gpt.c: Include `'. + (grub_gpt_partition_type_empty): Redefine with macro from + `'. + (gpt_partition_map_iterate): Adjust partition type comparison. + + Export `entry' as partmap-specific `part.data' struct. + (grub_gpt_header, grub_gpt_partentry): Move from here ... + + * include/grub/gpt_partition.h (grub_gpt_header) + (grub_gpt_partentry): ... to here (new file). + + * util/i386/pc/grub-setup.c: Include `'. + + (grub_gpt_partition_type_bios_boot): New const variable, defined + with macro from `'. + + (setup): Replace `first_start' with `embed_region', which keeps + track of the embed region (and is partmap-agnostic). + + Replace find_first_partition_start() with find_usable_region(), + which finds a usable region for embedding using partmap-specific + knowledge (supports PC/MSDOS and GPT). + + Fix all assumptions that the embed region start at sector 1, using + `embed_region.start' from now on. Similarly, use `embed_region.end' + rather than `first_start' to calculate available size. + + In grub_util_info() message, replace "into after the MBR" with an + indication of the specific sector our embed region starts at. + +2008-02-19 Robert Millan + + * DISTLIST: Replace `commands/ieee1275/halt.c' and + `commands/ieee1275/reboot.c' with `commands/halt.c' and + `commands/reboot.c'. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES) + (halt_mod_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES, reboot_mod_SOURCES) + (halt_mod_SOURCES): Likewise. + +2008-02-17 Christian Franke + + * commands/cat.c (grub_cmd_cat): Add break on GRUB_TERM_ESC key. + +2008-02-17 Robert Millan + + * util/i386/pc/grub-setup.c (setup): In find_first_partition_start(), + set `first_start' to 0 for non-PC/MSDOS partition maps. + +2008-02-16 Robert Millan + + * util/i386/pc/grub-setup.c (setup): In find_first_partition_start(), + do not assume partition map is PC/MSDOS before performing checks that + are specific to that layout. + +2008-02-13 Robert Millan + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Remove + `commands/i386/pc/halt.c' and `commands/i386/pc/reboot.c'. + * kern/i386/linuxbios/init.c (grub_halt, grub_reboot): Remove stubs. + +2008-02-13 Yoshinori K. Okuji + + * configure.ac: Only a cosmetic change on the handling of + -fno-stack-protector. + +2008-02-12 Alexandre Boeglin + + * conf/i386-efi.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/halt.c and reboot.c by commands/halt.c and + reboot.c. + (grub_install_SOURCES): Add halt.mod and reboot.mod. + (halt_mod_SOURCES): New variable. + (halt_mod_CFLAGS): Likewise. + (halt_mod_LDFLAGS): Likewise. + (reboot_mod_SOURCES): Likewise. + (reboot_mod_CFLAGS): Likewise. + (reboot_mod_LDFLAGS): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace + commands/ieee1275/halt.c and reboot.c by commands/halt.c and + reboot.c. + (halt_mod_SOURCES): Likewise. + (reboot_mod_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/reboot.c by commands/reboot.c. + (reboot_mod_SOURCES): Likewise. + + * commands/i386/pc/reboot.c: merge this file ... + + * commands/ieee1275/reboot.c: ... and this file ... + + * commands/reboot.c: ... to this file. + Add some precompiler directive to include the correct header for + each machine. + + * commands/ieee1275/halt.c: move this file ... + + * commands/halt.c: ... to here. + Add some precompiler directive to include the correct header for + each machine. + + * include/grub/efi/efi.h (grub_reboot): New function declaration. + (grub_halt): Likewise. + + * kern/efi/efi.c (grub_reboot): New function. + (grub_halt): Likewise. + +2008-02-12 Robert Millan + + * util/getroot.c (grub_guess_root_device): Inspect /dev/evms before + /dev (like it is done for /dev/mapper). This doesn't provide support + for EVMS, but at least it is now easy to identify the problem when it + arises. + +2008-02-11 Robert Millan + + * util/biosdisk.c (grub_util_biosdisk_open, linux_find_partition) + (grub_util_biosdisk_get_grub_dev): Check open() exit status by + comparing it with -1, not 0. + +2008-02-10 Robert Millan + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add `disk/raid.c' and + `disk/lvm.c'. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Move `disk/raid.c' and + `disk/lvm.c' to the end of the list. + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + +2008-02-10 Robert Millan + + * kern/main.c (grub_load_normal_mode): Do not reset `grub_errno'. Call + grub_print_error() instead. This will let user know why we're entering + rescue mode. + Based on suggestions from Sam Morris. + +2008-02-10 Alexandre Boeglin + + * normal/arg.c (grub_arg_parse): If one of the args is "--", call add_arg() + on remaining N args, instead of "--" arg N times. + +2008-02-09 Vesa Jaaskelainen + + * font/manager.c (unknown_glyph): Added variable for unknown glyph. + (fill_with_default_glyph): Changed to use unknown_glyph for fill + pattern for unknown glyphs. + +2008-02-09 Robert Millan + + * configure.ac: Probe for `help2man'. + * Makefile.in (builddir): New variable. + (HELP2MAN): Likewise. Set to `true' when @HELP2MAN@ doesn't provide it, + or otherwise add a few flags/options to it. + (install-local): For every executable utility or script that is + installed, invoke $(HELP2MAN) to install a manpage based on --help + output. + + * util/i386/pc/grub-install.in: Move down `update-grub_lib' sourcing, so + that it doesn't prevent --help from working in build tree. + + * util/i386/pc/grub-mkrescue.in (usage): Replace `grub-devel@gnu.org' + with `bug-grub@gnu.org'. + * util/powerpc/ieee1275/grub-mkrescue.in (usage): Likewise. + * util/update-grub.in (usage): New function. + Implement proper argument check, with support for --help and --version + (as well as existing -y). + +2008-02-09 Christian Franke + + * commands/cat.c (grub_cmd_cat): Print '\r' as hex to + avoid overwriting previous output. + * kern/rescue.c (grub_rescue_cmd_cat): Likewise. + +2008-02-09 Robert Millan + + * normal/menu.c (run_menu): If timeout is set to zero, don't bother + drawing the menu. + +2008-02-09 Robert Millan + + * commands/sleep.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `commands/sleep.c'. + (sleep_mod_SOURCES): New variable. + (sleep_mod_CFLAGS): Likewise. + (sleep_mod_LDFLAGS): Likewise. + +2008-02-09 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Add a pair of sanity checks for + situations in which we can deduce the RAID size and the superblock + doesn't match it. + +2008-02-09 Robert Millan + + * disk/lvm.c [GRUB_UTIL] (grub_lvm_memberlist): New function. Construct + and return a grub_diskmemberlist_t composed of LVM physical volumes. + [GRUB_UTIL] (grub_lvm_dev): Add `memberlist' member. + + * disk/raid.c [GRUB_UTIL] (grub_raid_memberlist): New function. Construct + and return a grub_diskmemberlist_t composed of physical array members. + [GRUB_UTIL] (grub_raid_dev): Add `memberlist' member. + + * include/grub/disk.h [GRUB_UTIL] (grub_disk_memberlist): New struct + prototype. + [GRUB_UTIL] (struct grub_disk_dev): Add `memberlist' function pointer. + [GRUB_UTIL] (struct grub_disk_memberlist): New struct declaration. + [GRUB_UTIL] (grub_disk_memberlist_t): New typedef. + + * util/grub-probe.c (probe): Move partmap probing code from here ... + (probe_partmap): ... to here. + (probe): Use probe_partmap() once for the disk we're probing, and + additionally, when such disk contains a memberlist() struct member, + once for each disk that is contained in the structure returned by + memberlist(). + +2008-02-09 Robert Millan + + * util/grub-probe.c (main): When `verbosity > 1', set `debug' + environment variable to 'all' in order to obtain debug output from + non-util/ code. + * util/i386/pc/grub-setup.c (main): Likewise. + +2008-02-08 Robert Millan + + * disk/raid.c (grub_raid_scan_device): Check for + `array->device[sb.this_disk.number]' rather than for + `array->device[sb.this_disk.number]->name', since the latter is not + guaranteed to be accessible. + +2008-02-08 Robert Millan + + * disk/raid.c: Update copyright. + * fs/cpio.c: Likewise. + * include/grub/raid.h: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * util/hostfs.c: Likewise. + +2008-02-08 Robert Millan + + * include/grub/raid.h (struct grub_raid_array): Change type of `device' + to a grub_disk_t array. + * disk/raid.c (grub_raid_read): Replace `device[x].disk' accesses with + `device[x]'. + (grub_raid_scan_device): Replace `device[x].name' accesses with + `device[x]->name'. Simplify initialization of `array->device[x]'. + +2008-02-08 Robert Millan + + * disk/raid.c (grub_raid_open, grub_raid_scan_device): Add a few + grub_dprintf() calls. + * kern/disk.c (grub_disk_read): Include grub_errmsg in out of range + error message. + +2008-02-07 Christian Franke + + * util/hostfs.c (grub_hostfs_open): Use fseeko and ftello + instead of fseek and ftell to support large files. + (grub_hostfs_read): Likewise. + +2008-02-07 Robert Millan + + Patch from Jeroen Dekkers. + * disk/raid.c (grub_raid_scan_device): Reset `grub_errno' on disk + failure, since successfully reading all array members might not be + required. + +2008-02-06 Robert Millan + + * util/grub-probe.c (probe): Simplify partmap probing (with the + assumption that the first word up to the underscore equals to + the module name). + +2008-02-06 Christian Franke + + * fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_NONE + (and set *ofs = 0) instead of GRUB_ERR_FILE_NOT_FOUND on + last block of a cpio or tar stream. + Check for "TRAILER!!!" instead of any empty data + block to detect last block of a cpio stream. + (grub_cpio_dir): Fix constness of variable np. + (grub_cpio_open): Return GRUB_ERR_FILE_NOT_FOUND if + cpio or tar trailer is detected. This fixes a crash + on open of a non existing file. + +2008-02-05 Bean + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Get physical + address of entry. + (grub_multiboot_load_elf64): Likewise. + (grub_multiboot): Initialize mbi structure. + + * util/grub-fstest.c: Don't include unused header file script.h. + + * conf/common.rmk (grub-fstest.c_DEPENDENCIES): Move to the beginning + of file. + (grub_fstest_SOURCES): Likewise. + +2008-02-05 Robert Millan + + * include/grub/term.h (GRUB_TERM_LEFT, GRUB_TERM_RIGHT) + (GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_HOME, GRUB_TERM_END) + (GRUB_TERM_DC, GRUB_TERM_PPAGE, GRUB_TERM_NPAGE, GRUB_TERM_ESC) + (GRUB_TERM_TAB, GRUB_TERM_BACKSPACE): New macros. + + * kern/i386/pc/startup.S: Include `'. + (translation_table): Replace hardcoded values with macros + provided by `'. + + * term/i386/pc/at_keyboard.c: Include `'. + (keyboard_map): Correct/add a few values, with macros provided + by `'. + (keyboard_map_shift): Zero values that don't differ from their + `keyboard_map' equivalents. + (grub_console_checkkey): Optimize KEYBOARD_STATUS_CAPS_LOCK toggling. + Discard the second scan code that is always sent by Caps lock. + Only use `keyboard_map_shift' when it provides a non-zero value, + otherwise fallback to `keyboard_map'. + +2008-02-04 Bean + + * Makefile.in (enable_grub_fstest): New variable. + + * conf/common.rmk (grub_fstest_init.lst): New rule. + (grub_fstest_init.h): Likewise. + (grub_fstest_init.c): Likewise. + (util/grub-fstest.c_DEPENDENCIES): New variable. + (grub_fstest_SOURCES): Likewise. + + * configure.ac (enable_grub_fstest): Check for --enable-grub-fstest. + + * util/grub-fstest.c: New file. + +2008-02-03 Yoshinori K. Okuji + + Make grub-setup handle a separate root device. + + * util/i386/pc/grub-setup.c (setup): Always open the root device, + so that the root device can be compared with the destination + device. + When embedding the core image, if the root and destination devices + are different, set ROOT_DRIVE to ROOT_DEV->DISK->ID. Otherwise, to + 0xFF. + When not embedding, set ROOT_DRIVE to 0xFF. + +2008-02-03 Yoshinori K. Okuji + + Add support for having a grub directory in a different drive. This + is still only the data handling part. + + * kern/i386/pc/startup.S (multiboot_trampoline): Set %dh to 0xFF. + (codestart): Save %dh in GRUB_ROOT_DRIVE. + (grub_root_drive): New variable. + + * kern/i386/pc/init.c (make_install_device): Use GRUB_ROOT_DRIVE + instead of GRUB_BOOT_DRIVE to construct a device name. Set + GRUB_ROOT_DRIVE to GRUB_BOOT_DRIVE if it is 0xFF, otherwise use it + as it was. + + * include/grub/i386/pc/kernel.h (grub_root_drive): New prototype. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_ROOT_DRIVE): New + macro. + (GRUB_BOOT_MACHINE_DRIVE_CHECK): Set to 0x4f. + + * boot/i386/pc/pxeboot.S (_start): Set %dh to 0xFF. For now, this + is bogus, because PXE booting does not specify any drive + correctly. + + * boot/i386/pc/lnxboot.S (reg_edx): Set the second byte to 0xFF. I + am not sure if this is really correct. + + * boot/i386/pc/cdboot.S: Set %dh to 0xFF, because the root drive + is always identical to the boot drive when booting from a CD. + + * boot/i386/pc/boot.S (MOV_MEM_TO_AL): Removed. Not needed any + longer. + (root_drive): New variable. + (real_start): Unconditionally set %dh to ROOT_DRIVE. + (setup_sectors): Push %dx right after popping it, because %dh will + be modified later. + (copy_buffer): Restore %dx. + +2008-02-03 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Rewrite most of image generation to + use `cdboot.img' for cdrom images. + +2008-02-03 Robert Millan + + * util/grub.d/00_header.in: Issue scripting commands for GRUB to + only setup gfxterm when `font' command has succeeded. + +2008-02-03 Robert Millan + + * loader/multiboot_loader.c [GRUB_MACHINE_LINUXBIOS] + (grub_rescue_cmd_multiboot_loader) + (grub_rescue_cmd_module_loader): Enable multiboot1 calls. + +2008-02-03 Pavel Roskin + + * kern/i386/pc/startup.S (grub_chainloader_real_boot): Pop + %edx and %esi from stack only after grub_gate_a20() is called. + grub_gate_a20() clobbers %edx. + +2008-02-03 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Bumped to 1.96. + + * DISTLIST: Added boot/i386/pc/cdboot.S, bus/pci.c, + commands/lspci.c,disk/memdisk.c, include/grub/pci.h, + include/grub/i386/pc/pci.h, video/readers/jpeg.c, and + video/readers/png.c. + +2008-02-03 Bean + + * conf/i386-pc.rmk (pkglib_IMAGES): Add cdboot.img. + (cdboot_img_SOURCES): New variable. + (cdboot_img_ASFLAGS): New variable. + (cdboot_img_LDFLAGS): New variable. + + * boot/i386/pc/cdboot.S: New file. + + * disk/i386/pc/biosdisk.c (cd_start): New variable. + (cd_count): Likewise. + (grub_biosdisk_get_drive): Add support for cd device. + (grub_biosdisk_call_hook): Likewise. + (grub_biosdisk_iterate): Likewise. + (grub_biosdisk_open): Likewise. + (GRUB_BIOSDISK_CDROM_RETRY_COUNT): New macro. + (grub_biosdisk_rw): Support reading from cd device. + (GRUB_MOD_INIT): Iterate cd devices. + + * include/grub/i386/pc/biosdisk.h (GRUB_BIOSDISK_FLAG_CDROM): New macro. + (GRUB_BIOSDISK_MACHINE_CDROM_START): Likewise. + (GRUB_BIOSDISK_MACHINE_CDROM_END): Likewise. + + * kern/i386/pc/init.c (make_install_device): Check for cd device. + +2008-02-02 Robert Millan + + * commands/read.c: New file. + * conf/common.rmk (pkglib_MODULES): Add `commands/read.c'. + (read_mod_SOURCES): New variable. + (read_mod_CFLAGS): Likewise. + (read_mod_LDFLAGS): Likewise. + +2008-02-02 Robert Millan + + * normal/main.c (grub_normal_execute): Check for `menu->size' when + determining whether menu has to be displayed. + +2008-02-02 Marco Gerards + + * bus/pci.c: New file. + + * include/grub/pci.h: Likewise. + + * include/grub/i386/pc/pci.h: Likewise. + + * commands/lspci.c: Likewise. + + * conf/i386-pc.rmk (pkglib_MODULES): Add `pci.mod' and + `lspci.mod'. + (pci_mod_SOURCES): New variable. + (pci_mod_CFLAGS): Likewise. + (pci_mod_LDFLAGS): Likewise. + (lspci_mod_SOURCES): Likewise. + (lspci_mod_CFLAGS): Likewise. + (lspci_mod_LDFLAGS): Likewise. + +2008-02-02 Bean + + * fs/ufs.c (INODE_BLKSZ): Fix incorrect value. + (grub_ufs_get_file_block): Fix indirect block calculation problem. + + * fs/xfs.c (grub_xfs_sblock): New member log2_dirblk. + (grub_xfs_btree_node): New structure. + (grub_xfs_btree_root): New structure. + (grub_xfs_inode): New members nblocks, extsize, nextents and btree. + (GRUB_XFS_EXTENT_OFFSET): Use exts instead of inode->data.extents. + (GRUB_XFS_EXTENT_BLOCK): Likewise. + (GRUB_XFS_EXTENT_SIZE): Likewise. + (grub_xfs_read_block): Support btree format type. + (grub_xfs_iterate_dir): Use NESTED_FUNC_ATTR in call_hook. + Use directory block as basic unit. + + * fs/fshelp.c (grub_fshelp_read_file): Bug fix for sparse block. + + * aclocal.m4 (grub_i386_CHECK_REGPARM_BUG): Define NESTED_FUNC_ATTR as + __attribute__ ((__regparm__ (1))). + +2008-02-01 Robert Millan + + Correct a mistake in previous commit. + + * conf/i386-pc.rmk (normal/execute.c_DEPENDENCIES): Move to the + top. + (normal/command.c_DEPENDENCIES): New variable. + +2008-02-01 Robert Millan + + * conf/i386-efi.rmk (normal/execute.c_DEPENDENCIES): Move to the + top. + (normal/command.c_DEPENDENCIES): New variable. + (grub-emu_DEPENDENCIES, normal_mod_DEPENDENCIES): Remove variables. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + (grub_emu_SOURCES): Add `fs/fshelp.c'. + + * genmk.rb: Add `$(#{src}_DEPENDENCIES)' in targets that require it. + +2008-02-01 Robert Millan + + * kern/disk.c (grub_disk_read, grub_disk_write): Add grub_dprintf() + call at beginning of function. + +2008-01-31 Pavel Roskin + + * util/powerpc/ieee1275/grub-mkrescue.in: New file. + * conf/powerpc-ieee1275.rmk (bin_SCRIPTS): New variable. + (grub_mkrescue_SOURCES): Likewise. + * DISTLIST: Add util/powerpc/ieee1275/grub-mkrescue.in. + +2008-01-30 Robert Millan + + * conf/i386-pc.rmk (sbin_UTILITIES): Remove `grub-probe'. + (util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Moved from here ... + * conf/common.rmk (util/grub-probe.c_DEPENDENCIES) + (grub_probe_SOURCES): ... to here. + + * conf/i386-efi.rmk (sbin_UTILITIES): Remove `grub-probe'. + (util/grub-probe.c_DEPENDENCIES, grub_probe_SOURCES): Remove. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + +2008-01-30 Tristan Gingold + + * kern/rescue.c: Silently accept empty lines. + +2008-01-29 Bean + + * boot/i386/pc/lnxboot.S (data_start): Code cleanup. + (real_code_2): Code cleanup and change comment style. + (move_memory): Avoid using 32-bit address mode. + +2008-01-29 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add `png.mod'. + (png_mod_SOURCES): New variable. + (png_mod_CFLAGS): Likewise. + (png_mod_LDFLAGS): Likewise. + + * video/readers/png.c: New file. + +2008-01-28 Robert Millan + + * include/grub/i386/linuxbios/kernel.h (GRUB_MOD_GAP): New macro. + * kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Remove + `ifndef GRUB_MOD_GAP' hack. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-27 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_arch_modules_addr): Skip + `GRUB_MOD_GAP' for platforms in which it's not defined. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-27 Robert Millan + + Get grub-emu to build again (including parallel builds). + + * conf/i386-pc.rmk (util/grub-emu.c_DEPENDENCIES): Remove variable. + Split into ... + (util/grub-emu.c_DEPENDENCIES): ... this, ... + (normal/execute.c_DEPENDENCIES): ... this, ... + (grub-emu_DEPENDENCIES): ... and this. + + * conf/i386-efi.rmk: Likewise. + * conf/i386-linuxbios.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + (grub_emu_SOURCES): Remove duplicated `kern/file.c'. + +2008-01-27 Robert Millan + + * NEWS: Add a few items. + +2008-01-27 Robert Millan + + Fix parallel builds with grub-emu. Based on earlier commit for + grub-probe and grub-setup. + + * conf/i386-pc.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-efi.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-linuxbios.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/i386-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + * conf/powerpc-ieee1275.rmk (grub-emu_DEPENDENCIES): Renamed to ... + (util/grub-emu.c_DEPENDENCIES): ... this. + +2008-01-27 Pavel Roskin + + * include/grub/powerpc/ieee1275/kernel.h: Introduce GRUB_MOD_GAP + to create a gap between _end and the modules added to the image + with grub-mkrescue. That fixes "CLAIM failed" on PowerMAC. + * kern/powerpc/ieee1275/init.c: Use GRUB_MOD_GAP. + * util/elf/grub-mkimage.c (add_segments): Likewise. + +2008-01-26 Pavel Roskin + + * kern/dl.c (grub_dl_load): Don't abort if prefix is not set, + just return an error. + +2008-01-26 Bean + + * fs/reiserfs.c (grub_fshelp_node): New member next_offset. + (grub_reiserfs_get_item): Save offset of the next item. + (grub_reiserfs_iterate_dir): Use next_offset to find next item. + +2008-01-25 Robert Millan + + * conf/i386-pc.rmk (grub_setup_SOURCES, grub_emu_SOURCES): Regroup to + make all filesystem sources appear together (possibly fixing omissions + while at it). + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Likewise. Additionally, + add `kern/file.c'. + * conf/i386-efi.rmk (grub_probe_SOURCES): Likewise. + * conf/i386-ieee1275.rmk (grub_probe_SOURCES): Likewise. + * conf/i386-linuxbios.rmk (grub_probe_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Likewise. + + * util/grub-probe.c: Include `' and `'. + (probe): Add a sanity check to make sure of our ability to read + requested files when probing for filesystem type. + + * genmk.rb: Update copyright year (2007). + + * include/grub/fs.h (grub_fat_init, grub_fat_fini, grub_ext2_init) + (grub_ext2_fini, grub_ufs_init, grub_ufs_fini, grub_minix_init) + (grub_minix_fini, grub_hfs_init, grub_hfs_fini, grub_jfs_init) + (grub_jfs_fini, grub_xfs_init, grub_xfs_fini, grub_affs_init) + (grub_affs_fini, grub_sfs_init, grub_sfs_fini, grub_iso9660_init) + : Remove function prototypes. + +2008-01-25 Robert Millan + + Revert my previous commits (based on wrong assumption of how grub_errno + works). + + * kern/disk.c (grub_disk_open): Stop resetting grub_errno. + * kern/file.c (grub_file_open): Likewise. + +2008-01-24 Pavel Roskin + + * include/grub/ieee1275/ieee1275.h: Introduce flag for firmwares + that hang if GRUB tries to setup colors. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Don't set + colors for firmwares that don't support it. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): + Recognize Open Hack'Ware, set flags to work around its + limitations. + +2008-01-24 Robert Millan + + * kern/file.c (grub_file_open): Do not account previous failures of + unrelated functions when grub_errno is checked for. + Reported by Oleg Strikov. + +2008-01-24 Bean + + * fs/ufs.c (GRUB_UFS_VOLNAME_LEN): New macro. + (grub_ufs_sblock): New member volume name. + (grub_ufs_find_file): Fix string copy bug. + (grub_ufs_label): Implement this function properly. + + * fs/hfs.c (grub_hfs_cnid_type): New enum. + (grub_hfs_iterate_records): Use the correct file number for extents + and catalog file. Fix problem in next index calculation. + (grub_hfs_find_node): Replace recursive function call with loop. + (grub_hfs_iterate_dir): Replace recursive function call with loop. + +2008-01-23 Robert Millan + + * include/grub/i386/ieee1275/loader.h: Include `', + `' and `'. + (grub_multiboot2_real_boot): New function prototype. + + * include/grub/i386/pc/memory.h: Include `'. + [!GRUB_MACHINE_IEEE1275] (grub_lower_mem, grub_upper_mem): Disable. + + * kern/i386/ieee1275/init.c (grub_os_area_addr) + (grub_os_area_size, grub_lower_mem, grub_upper_mem): Remove variables. + +2008-01-23 Robert Millan + + * kern/mm.c (grub_mm_init_region): Replace grub_dprintf() call with + #ifdef'ed out grub_printf(). + +2008-01-23 Robert Millan + + * term/i386/pc/at_keyboard.c (grub_keyboard_isr): #ifdef out + grub_dprintf calls, since they make "debug=all" mode unusable. + (grub_console_checkkey): Likewise. + +2008-01-23 Robert Millan + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add + `term/i386/pc/at_keyboard.c'. + (pkglib_MODULES): Add `serial.mod'. + (serial_mod_SOURCES): New variable. + (serial_mod_CFLAGS): Likewise. + (serial_mod_LDFLAGS): Likewise. + + * include/grub/i386/ieee1275/console.h: Add `'. Remove + `'. + (grub_keyboard_controller_init): New function prototype. + (grub_console_checkkey): Likewise. + (grub_console_getkey): Likewise. + + * kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize AT + keyboard on i386. + + * term/ieee1275/ofconsole.c (grub_ofconsole_term): On i386, use + grub_ofconsole_checkkey() and grub_ofconsole_getkey() for input. + +2008-01-23 Robert Millan + + * kern/i386/pc/init.c (make_install_device): When memdisk image is + present, "(memdisk)/boot/grub" becomes the default prefix. + + * util/i386/pc/grub-mkrescue.in: Switch to a minimal core.img plus + a memdisk tarball with all the modules. Add --overlay=DIR option that + allows users to overlay additional files into the image. + +2008-01-23 Robert Millan + + * conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Add `machine/loader.h' + and `machine/memory.h'. + (pkglib_MODULES): Add `multiboot.mod' and `_multiboot.mod'. + (_multiboot_mod_SOURCES): New variable. + (_multiboot_mod_CFLAGS): Likewise. + (_multiboot_mod_LDFLAGS): Likewise. + (multiboot_mod_SOURCES): Likewise. + (multiboot_mod_CFLAGS): Likewise. + (multiboot_mod_LDFLAGS): Likewise. + + * include/grub/i386/ieee1275/loader.h: New file. + + * include/grub/i386/ieee1275/machine.h: Likewise. + + * include/grub/i386/ieee1275/memory.h: Likewise. + + * include/grub/i386/pc/init.h (grub_os_area_addr): Remove (redundant) + variable declaration. + (grub_os_area_size): Likewise. + + * kern/i386/ieee1275/init.c (grub_os_area_addr, grub_os_area_size) + (grub_lower_mem, grub_upper_mem): New variables. + (grub_stop_floppy): New function (just to make + grub_multiboot2_real_boot() happy). + + * kern/i386/ieee1275/startup.S: Include `', + `', `' and `'. + (grub_stop): New function. + Include `"../realmode.S"' and `"../loader.S"'. + + * loader/multiboot_loader.c: Include `'. + Replace `__i386__' #ifdefs with `GRUB_MACHINE_PCBIOS'. + + * loader/powerpc/ieee1275/multiboot2.c (grub_mb2_arch_boot): On i386, + rely on grub_multiboot2_real_boot() for final boot. + +2008-01-22 Robert Millan + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): When + `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag is set, skip any + device that doesn't look like an SD card. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add + `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' flag. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_set_flag): Detect + OLPC laptop, and set `GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY' when + found. + +2008-01-22 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_claim_heap): Add sanity check to + avoid claiming over our own code. + +2008-01-22 Bean + + * conf/i386-pc.rmk (pkglib_MODULES): Add `jpeg.mod'. + (jpeg_mod_SOURCES): New variable. + (jpeg_mod_CFLAGS): Likewise. + (jpeg_mod_LDFLAGS): Likewise. + + * video/readers/jpeg.c : New file. + +2008-01-22 Bean + + * fs/cpio.c (grub_cpio_find_file): Return GRUB_ERR_FILE_NOT_FOUND when + there are no more items. + +2008-01-21 Robert Millan + + * kern/mm.c (grub_mm_init_region): Improve debug message. + +2008-01-21 Robert Millan + + * conf/i386-pc.rmk (GRUB_MEMORY_MACHINE_LINK_ADDR): New variable. + (kernel_img_LDFLAGS): Use `GRUB_MEMORY_MACHINE_LINK_ADDR' as link + address. + (grub_mkimage_CFLAGS): Propagate `GRUB_MEMORY_MACHINE_LINK_ADDR' as + a C macro. + * include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_UPPER): New macro. + Indicates start of upper memory. + * util/i386/pc/grub-mkimage.c: Include `'. + (generate_image): Abort when image size is big enough to corrupt + upper memory. + + * include/grub/i386/pc/vga.h: Include `'. + (GRUB_MEMORY_MACHINE_VGA_ADDR): Alias for `GRUB_MEMORY_MACHINE_UPPER'. + * term/i386/pc/vga.c (VGA_MEM): Use `GRUB_MEMORY_MACHINE_VGA_ADDR' + instead of hardcoding 0xA0000. + * video/i386/pc/vbe.c: Include `'. + (grub_vbe_set_video_mode): Use `GRUB_MEMORY_MACHINE_VGA_ADDR' + instead of hardcoding 0xA0000. + +2008-01-21 Robert Millan + + * disk/memdisk.c (memdisk_size): New variable. + (grub_memdisk_open): Replace grub_arch_memdisk_size() call with + `memdisk_size'. + (grub_memdisk_init): Initialize `memdisk_size'. Reallocate memdisk + image to dynamic memory. + (grub_memdisk_fini): Replace grub_arch_memdisk_size() call with + `memdisk_size'. Free memdisk block. + +2008-01-21 Robert Millan + + Fix detection of very small filesystems (like tar). + + * fs/reiserfs.c (grub_reiserfs_mount): When disk is too small to + contain a ReiserFS, abort with GRUB_ERR_BAD_FS rather than + GRUB_ERR_OUT_OF_RANGE (which made the upper layer think there's + a problem with this disk). + +2008-01-21 Robert Millan + + * disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Add debug message + on grub_biosdisk_rw_standard() error. + +2008-01-21 Robert Millan + + * include/grub/ieee1275/ieee1275.h: Add 2008 to Copyright line for + recent changes. + * kern/elf.c: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + +2008-01-21 Robert Millan + + * include/grub/i386/pc/kernel.h: Include `'. + + * include/grub/kernel.h (grub_arch_memdisk_addr) + (grub_arch_memdisk_size): Moved from here ... + + * include/grub/i386/pc/kernel.h (grub_arch_memdisk_addr) + (grub_arch_memdisk_size): ... to here. + +2008-01-21 Robert Millan + + Mostly based on bugfix from Bean. + + * kern/elf.c (grub_elf32_phdr_iterate): Use `NESTED_FUNC_ATTR' + attribute with hook() parameter. + (grub_elf32_load): Use `NESTED_FUNC_ATTR' with grub_elf32_load_segment() + declaration. + (grub_elf64_phdr_iterate): Use `NESTED_FUNC_ATTR' + attribute with hook() parameter. + (grub_elf64_load): Use `NESTED_FUNC_ATTR' with grub_elf64_load_segment() + declaration. + +2008-01-21 Robert Millan + + * conf/i386-pc.rmk (kernel_img_HEADERS): Add `machine/kernel.h'. + (pkglib_MODULES): Add `memdisk.mod'. + (memdisk_mod_SOURCES): New variable. + (memdisk_mod_CFLAGS): Likewise. + (memdisk_mod_LDFLAGS): Likewise. + + * disk/memdisk.c: New file. + + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_MEMDISK_ID'. + + * include/grub/i386/pc/kernel.h + (GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE): New macro. + (GRUB_KERNEL_MACHINE_PREFIX): Increment by 4. + (grub_kernel_image_size): New variable declaration. + (grub_total_module_size): Likewise. + (grub_memdisk_image_size): Likewise. + + * include/grub/i386/pc/memory.h + (GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR): New macro. + + * include/grub/kernel.h: Include `'. + (grub_arch_memdisk_addr): New variable declaration. + (grub_arch_memdisk_size): Likewise. + + * kern/i386/pc/init.c (grub_arch_memdisk_addr): New function. + (grub_arch_memdisk_size): Likewise. + + * kern/i386/pc/startup.S (grub_memdisk_image_size): New variable. + (codestart): Replace hardcoded `0x100000' with + `GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR' macro. + + * util/i386/pc/grub-mkimage.c: Include `'. + (generate_image): Add `memdisk_path' parameter. When `memdisk_path' is + not NULL, append the contents of the file it refers to, at the end of + the compressed kernel image. Initialize `grub_memdisk_image_size' + variable (at `GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE' offset). + (options): Add "memdisk"|'m' option. + (main): Parse --memdisk|-m option, and pass user-provided path as + parameter to generate_image(). + +2008-01-20 Robert Millan + + * kern/sparc64/ieee1275/openfw.c (grub_devalias_iterate): Copy debug + grub_dprintf() calls from here ... + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): ... to here. + +2008-01-20 Robert Millan + + Fix detection of "real mode" when /options/real-mode? doesn't exist. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_mmu): New variable + declaration. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_mmu): New variable. + (grub_ieee1275_find_options): If `grub_ieee1275_mmu' is 0, set + `GRUB_IEEE1275_FLAG_REAL_MODE'. + (cmain): Initialize `grub_ieee1275_mmu' (using /chosen/mmu integer + property). + * kern/powerpc/ieee1275/openfw.c (grub_map): Rely on pre-initialized + `grub_ieee1275_mmu' rather than obtaining a handler on every call. + +2008-01-19 Robert Millan + + Get rid of confusing function (superseded by + `grub_ieee1275_get_integer_property') + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_decode_int_4): Remove + prototype. + * kern/ieee1275/ieee1275.c (grub_ieee1275_decode_int_4): Remove + function. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid use of + grub_ieee1275_decode_int_4(), by obtaining integer properties directly + in native endianness from grub_ieee1275_get_integer_property(). + +2008-01-19 Robert Millan + + * kern/powerpc/ieee1275/openfw.c (grub_halt): Issue "power-off" + command after "shut-down", since implementations differ on which + the command for halt is. + +2008-01-19 Robert Millan + + * include/grub/i386/linuxbios/console.h: Add header protection. + (grub_keyboard_controller_init): New function prototype. + * term/i386/pc/at_keyboard.c (KEYBOARD_COMMAND_ISREADY): New macro. + (KEYBOARD_COMMAND_READ): Likewise. + (KEYBOARD_COMMAND_WRITE): Likewise. + (KEYBOARD_SCANCODE_SET1): Likewise. + (grub_keyboard_controller_write): New function. + (grub_keyboard_controller_read): Likewise. + (grub_keyboard_controller_init): Likewise. + + * term/i386/pc/console.c: Include `'. + (grub_console_init): On coreboot/LinuxBIOS, call + grub_keyboard_controller_init(). + +2008-01-19 Robert Millan + + PowerPC changes provided by Pavel Roskin. + + * kern/powerpc/ieee1275/cmain.c (cmain): Don't take any arguments. + * kern/powerpc/ieee1275/crt0.S: Store r5 in grub_ieee1275_entry_fn, + don't rely on cmain() doing it. + * kern/i386/ieee1275/startup.S (_start): Store %eax in + grub_ieee1275_entry_fn, don't rely on cmain() doing it. + +2008-01-16 Robert Millan + + * include/grub/i386/linuxbios/memory.h + (GRUB_MEMORY_MACHINE_LINUXBIOS_TABLE_ADDR): Remove macro. + * kern/i386/linuxbios/table.c (grub_linuxbios_table_iterate): Do not + receive `table_header' as argument. Instead, probe for it in the + known memory ranges where it can be present. + (grub_available_iterate): Do not pass a fixed `table_header' address + to grub_linuxbios_table_iterate(). + +2008-01-15 Robert Millan + + * configure.ac: Add `i386-ieee1275' to the list of supported targets. + * conf/i386-ieee1275.rmk: New file. + * include/grub/i386/ieee1275/console.h: Likewise. + * include/grub/i386/ieee1275/ieee1275.h: Likewise. + * include/grub/i386/ieee1275/kernel.h: Likewise. + * include/grub/i386/ieee1275/time.h: Likewise. + * kern/i386/ieee1275/init.c: Likewise. + * kern/i386/ieee1275/startup.S: Likewise. + +2008-01-15 Robert Millan + + * kern/misc.c (grub_vsprintf): Do not reset `longlongfmt' to zero + when pointers are 32-bit (but still do set it to one when they are + 64-bit). + +2008-01-15 Robert Millan + + * include/grub/ieee1275/ieee1275.h + (grub_ieee1275_get_integer_property): New function prototype. + + * kern/ieee1275/ieee1275.c: Include `'. + (grub_ieee1275_get_integer_property): New function. Wraps around + grub_ieee1275_get_property() to handle endianness. + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Replace + grub_ieee1275_get_property() with grub_ieee1275_get_integer_property() + where appropriate. + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Likewise. + (grub_map): Likewise. + * kern/sparc64/ieee1275/openfw.c (grub_map): Likewise. + +2008-01-15 Bean + + * normal/execute.c (grub_script_exec_argument_to_string): Check for undefined variable. + (grub_script_execute_cmdline): Reset grub_errno. + + * normal/main.c (read_config_file): Reset grub_errno. + + * normal/parse.y (script_init): New. + (script): Move function and menuentry here. + (delimiter): New. + (command): Add delimiter at the end of command. + (commands): Adjust to match the new command. + (commandblock): Remove grub_script_lexer_record_start. + (menuentry): Add grub_script_lexer_record_start, use the new commands. + (if): Use the new commands. + + * conf/common.rmk (pkgdata_MODULES): Add echo.mod. + +2008-01-15 Robert Millan + + * normal/menu.c (run_menu): Move timeout message from here ... + (print_timeout): ... to here. + (run_menu): Use print_timeout() once during initial draw to print + the whole message, and again in every clock tick to update only + the number of seconds. + +2008-01-15 Robert Millan + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Obtain + actual size of `available' from grub_ieee1275_get_property(), and + restrict parsing to that bound. + +2008-01-15 Christian Franke + + * util/grub-emu.c: Replace by . + (argp_program_version): Remove variable. + (argp_program_bug_address): Likewise. + (options): Convert from struct argp_option to struct option. + (struct arguments): Remove. + (parse_opt): Remove. + (usage): New function. + (main): Replace struct args members by simple variables. + Replace argp_parse() by getopt_long(). + Add switch to evaluate options. + Add missing "(...)" around root_dev in prefix string. + +2008-01-14 Robert Millan + + * kern/powerpc/ieee1275/init.c (grub_exit): Reimplement as a wrapper + for grub_ieee1275_exit(), in order to improve portability. + +2008-01-14 Robert Millan + + * util/grub.d/10_linux.in (prefix): Define. + (exec_prefix): Likewise. Both definitions are later used by `libdir'. + +2008-01-13 Pavel Roskin + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Don't use + grub_errno if no errors have been detected. + +2008-01-12 Robert Millan + + * include/grub/util/getroot.h (grub_dev_abstraction_types): New enum. + (grub_util_get_dev_abstraction): New function prototype. + + * util/getroot.c: Include `' + (grub_util_get_grub_dev): Move detection of abstraction type to ... + (grub_util_get_dev_abstraction): ... here (new function). + + * util/grub-probe.c: Convert PRINT_* to an enum. Add + `PRINT_ABSTRACTION'. + (probe): Probe for abstraction type when requested. + (main): Understand `--target=abstraction'. + + * util/i386/efi/grub-install.in: Add abstraction module to core + image when it is found to be necessary. + * util/i386/pc/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + + * util/update-grub_lib.in (font_path): Return system path without + converting to GRUB path. + * util/update-grub.in: Convert system path returned by font_path() + to a GRUB path. Use `grub-probe -t abstraction' to determine what + abstraction module is needed for loading fonts (if any). Export + that as `GRUB_PRELOAD_MODULES'. + * util/grub.d/00_header.in: Process `GRUB_PRELOAD_MODULES' (print + insmod commands). + +2008-01-12 Yoshinori K. Okuji + + Remove some unused code from reiserfs. + + * fs/reiserfs.c (struct grub_reiserfs_key) + [GRUB_REISERFS_KEYV2_BITFIELD]: Removed offset and type. + (struct grub_reiserfs_node_body): Removed. + (grub_reiserfs_get_key_v2_type) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_get_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_offset) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_set_key_type) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_iterate_dir) [GRUB_REISERFS_KEYV2_BITFIELD]: + Likewise. + (grub_reiserfs_open) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + (grub_reiserfs_read) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + (grub_reiserfs_dir) [GRUB_REISERFS_KEYV2_BITFIELD]: Likewise. + +2008-01-10 Robert Millan + + * util/update-grub_lib.in (grub_file_is_not_garbage): New function. + Determines if a file is garbage left by packaging systems, etc. + * util/update-grub.in: Use grub_file_is_not_garbage() as a condition + for processing /etc/grub.d scripts. + * util/grub.d/10_hurd.in: Fix `GRUB_DISTRIBUTOR' comparison. + * util/grub.d/10_linux.in: Likewise. Use grub_file_is_not_garbage() + as a condition for processing Linux images. + +2008-01-10 Pavel Roskin + + * include/grub/powerpc/libgcc.h (__ucmpdi2): New export. Needed + to compile reiserfs.c on PowerPC. + +2008-01-10 Robert Millan + + * kern/device.c (grub_device_iterate): Do not abort device iteration + when one of the devices cannot be opened. + * kern/disk.c (grub_disk_open): Do not account previous failures of + unrelated functions when grub_errno is checked for. + +2008-01-08 Robert Millan + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): For + `! grub_linux_is_bzimage', change order of address comparison to make + it more intuitive, and improve "too big zImage" error message. + +2008-01-08 Robert Millan + + * Makefile.in (uninstall): Handle `$(update-grub_SCRIPTS)' and + `$(update-grub_DATA)'. + (distcheck): Fix race condition when invoking `$(MAKE)' on multiple + targets. + +2008-01-07 Robert Millan + + * boot/i386/pc/boot.S (boot_drive_check): Add a comment indicating + which instruction is modified by grub-setup during installation + (since it wasn't obvious by only looking at this file). + +2008-01-07 Robert Millan + + * TODO: Rewrite. Just refer to the wiki and the BTS instead of + listing actual TODO items. + +2008-01-06 Yoshinori K. Okuji + + * fs/reiserfs.c (grub_reiserfs_get_key_v2_type): Handle endianness + correctly. + (grub_reiserfs_get_key_offset): Likewise. + (grub_reiserfs_set_key_offset): Likewise. + (grub_reiserfs_set_key_type): Likewise. + (grub_reiserfs_iterate_dir): Return 1 if found, otherwise 0. + + (GRUB_REISERFS_KEYV2_BITFIELD): Undefined. Probably it would be + better to remove the bitfield version completely. + +2008-01-06 Yoshinori K. Okuji + + * fs/reiserfs.c (grub_reiserfs_iterate_dir): ENTRY_ITEM must be + allocated from the heap, due to the fshelp implementation. + (grub_reiserfs_dir): Free NODE, due to the same reason. + +2008-01-06 Yoshinori K. Okuji + + Mostly from Vincent Pelletier: + + * fs/reiserfs.c: New file. + + * conf/common.rmk (pkglib_MODULES): Added reiserfs.mod. + (reiserfs_mod_SOURCES): New variable. + (reiserfs_mod_CFLAGS): Likewise. + (reiserfs_mod_LDFLAGS): Likewise. + + * DISTLIST: Added boot/i386/pc/lnxboot.S, commands/hexdump.c, + disk/ata.c, fs/cpio.c, fs/ntfscomp.c, fs/reiserfs.c, + include/grub/ntfs.h, include/grub/i386/pc/machine.h, and + normal/color.c. + +2008-01-06 Robert Millan + + * normal/color.c: Remove `'. + +2008-01-05 Jeroen Dekkers + + * include/grub/normal.h: Include . + +2008-01-05 Robert Millan + + * util/i386/pc/grub-setup.c (usage): Replace obsolete `(hd0,0)' in + usage example with `(hd0,1)'. + Reported by Samuel Thibault. + +2008-01-05 Robert Millan + + * kern/i386/loader.S (grub_linux_is_bzimage): New variable. + (grub_linux_boot_zimage): Rename to ... + (grub_linux_boot): ... this. + (grub_linux_boot_bzimage): Merge with `grub_linux_boot_zimage'. + (grub_linux_boot_zimage): Conditionalize zImage copy. + + * include/grub/i386/loader.h (grub_linux_is_bzimage): Add prototype. + (grub_linux_boot_bzimage): Remove prototype. + (grub_linux_boot_zimage): Rename to ... + (grub_linux_boot): ... this. + + * loader/i386/pc/linux.c (big_linux): Replace with `grub_linux_is_bzimage'. + (grub_linux_boot): Remove function. + +2008-01-05 Robert Millan + + * include/grub/normal.h (grub_env_write_color_normal): New prototype. + (grub_env_write_color_highlight): Likewise. + (grub_wait_after_message): Likewise. + + * normal/color.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `normal/color.c'. + (normal_mod_DEPENDENCIES): Likewise. + + * normal/menu_entry.c (run): Rely on grub_wait_after_message() + for waiting after a message is printed. + * normal/main.c (read_config_file): Likewise. + (grub_normal_init): Register grub_env_write_color_normal() and + grub_env_write_color_highlight() hooks. Mark `color_normal' and + `color_highlight' variables as global. + + * normal/menu.c (grub_wait_after_message): New function. + (grub_color_menu_normal): New variable. Replaces ... + (GRUB_COLOR_MENU_NORMAL): ... this macro. + (grub_color_menu_highlight): New variable. Replaces ... + (GRUB_COLOR_MENU_HIGHLIGHT): ... this macro. + (draw_border): Set color state to `GRUB_TERM_COLOR_NORMAL' instead of + `GRUB_TERM_COLOR_STANDARD'. + (print_message): Use `grub_setcolorstate' to reload colors. Rename + `normal_code' and `highlight_code' to `old_color_normal' and + `old_color_highlight', respectively. + (grub_menu_init_page): Update colors when drawing the menu, based on + `menu_color_normal' and `menu_color_highlight' variables. + (grub_menu_run): Rely on grub_wait_after_message() for waiting after + a message is printed. + +2008-01-05 Robert Millan + + * kern/env.c (grub_env_context_open): Propagate hooks for global + variables to new context. + + * kern/main.c (grub_set_root_dev): Export `root' variable. + +2008-01-05 Robert Millan + + * util/biosdisk.c (get_os_disk): Check for devfs-style IDE and SCSI + discs unconditionally, since udev and others have options to provide + them. + +2008-01-05 Robert Millan + + * normal/completion.c (iterate_dir): Skip `.' and `..' directories. + +2008-01-04 Christian Franke + + * kern/i386/pc/init.c (grub_machine_init): Fix evaluation + of eisa_mmap. + +2008-01-03 Pavel Roskin + + * kern/i386/linuxbios/init.c: Put "void" to all function + declarations with no arguments. + * kern/powerpc/ieee1275/init.c: Likewise. + * term/i386/pc/at_keyboard.c: Likewise. + * term/i386/pc/vga_text.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + +2008-01-02 Robert Millan + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Improve error + message when loaded image is out of bounds. + (grub_multiboot_load_elf64): Likewise. + +2008-01-02 Pavel Roskin + + * util/grub.d/10_linux.in: Try version without ".old" when + looking for initrd. It's better to use initrd from the newer + kernel of the same version than no initrd at all. + +2008-01-01 Robert Millan + + * util/biosdisk.c (get_os_disk): Fix check for IDE or SCSI discs. + +2008-01-01 Vesa Jaaskelainen + + * include/grub/video.h: Added grub_video_unmap_color and + grub_video_get_active_render_target. + (grub_video_adapter): Added unmap_color and get_active_render_target. + + * video/video.c: Added grub_video_unmap_color and + grub_video_get_active_render_target. + (grub_video_get_info): Changed method to accept NULL pointer as an + argument to allow detection of active video adapter. + + * video/i386/pc/vbe.c: Renamed grub_video_vbe_unmap_color as + grub_video_vbe_unmap_color_int. + Added grub_video_vbe_unmap_color and + grub_video_vbe_get_active_render_target. + (grub_video_vbe_adapter): Added unmap_color and + get_active_render_target. + + * video/i386/pc/vbeblit.c: Replaced grub_video_vbe_unmap_color usage + with grub_video_vbe_unmap_color_int. + + * term/gfxterm.c (DEFAULT_STANDARD_COLOR): Added. + (DEFAULT_NORMAL_COLOR): Likewise. + (DEFAULT_HIGHLIGHT_COLOR) Likewise. + (DEFAULT_FG_COLOR): Removed. + (DEFAULT_BG_COLOR): Likewise. + (DEFAULT_CURSOR_COLOR): Changed value. + (grub_virtual_screen): Added standard_color_setting, + normal_color_setting, highlight_color_setting and term_color. + (grub_virtual_screen): Removed fg_color_setting and bg_color_setting. + (bitmap_width): Added. + (bitmap_height): Likewise. + (bitmap): Likewise. + (set_term_color): Likewise. + (grub_virtual_screen_setup): Changed to use new terminal coloring + settings. + (grub_gfxterm_init): Added init for bitmap. + (grub_gfxterm_fini): Added destroy for bitmap. + (redraw_screen_rect): Updated to use background bitmap and new + terminal coloring. + (scroll_up): Added optimization for case when there is no bitmap. + (grub_gfxterm_cls): Fixed to use correct background color. + (grub_virtual_screen_setcolorstate): Changed to use new terminal + coloring. + (grub_virtual_screen_setcolor): Likewise. + (grub_virtual_screen_getcolor): Added. + (grub_gfxterm_background_image_cmd): Likewise. + (grub_video_term): Added setcolor and getcolor. + (MOD_INIT): Added registration of background_image command. + (MOD_TERM): Added unregistration for background_image command. + +2007-12-30 Pavel Roskin + + * loader/multiboot_loader.c: Fix multiboot command + unregistration. Fix all typos in the word "multiboot". + +2007-12-29 Pavel Roskin + + * util/grub.d/10_linux.in: Refactor search for initrd. Add + support for initrd names used in Fedora. + +2007-12-26 Bean + + * conf/common.rmk (pkgdata_MODULES): Add cpio.mod. + (cpio_mod_SOURCES): New variable. + (cpio_mod_CFLAGS): Likewise. + (cpio_mod_LDFLAGS): Likewise. + + * fs/cpio.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add cpio.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + +2007-12-25 Robert Millan + + * include/grub/term.h (struct grub_term): Add `getcolor' function. + (grub_getcolor): New function. + + * kern/term.c (grub_getcolor): New function. + * normal/menu.c (GRUB_COLOR_MENU_NORMAL): New macro. + (GRUB_COLOR_MENU_HIGHLIGHT): New macro. + (print_entry): Set normal and highlight colors to + `GRUB_COLOR_MENU_NORMAL' and `GRUB_COLOR_MENU_HIGHLIGHT', + respectively, before printing and restore them to old + values afterwards. + (grub_menu_init_page): Likewise. Fill an additional colored space + that would otherwise be left blank. + + * term/efi/console.c (grub_console_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + * term/i386/pc/console.c (grub_console_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + * term/ieee1275/ofconsole.c (grub_ofconsole_getcolor): New function. + (struct grub_console_term.getcolor): New variable. + + * term/i386/pc/serial.c (grub_serial_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/i386/pc/vesafb.c (grub_virtual_screen_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/i386/pc/vga.c (grub_vga_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + * term/gfxterm.c (grub_virtual_screen_setcolor): Remove function. + (struct grub_console_term.setcolor): Remove variable. + +2007-12-25 Robert Millan + + * configure.ac: Search for possible unifont.hex locations, and + define UNIFONT_HEX if found. + + * Makefile.in (UNIFONT_HEX): Define variable. + (DATA): Rename to ... + (PKGLIB): ... this. Update all users. + (PKGDATA): New variable. + (pkgdata_IMAGES): Rename to ... + (pkglib_IMAGES): ... this. Update all users. + (pkgdata_MODULES): Rename to ... + (pkglib_MODULES): ... this. Update all users. + (pkgdata_PROGRAMS): Rename to ... + (pkglib_PROGRAMS): ... this. Update all users. + (pkgdata_DATA): Rename to ... + (pkglib_DATA): ... this. Update all users. + (CLEANFILES): Redefine to `$(pkglib_DATA) $(pkgdata_DATA)'. + (unicode.pff, ascii.pff): New rules. + (all-local): Add `$(PKGDATA)' dependency. + (install-local): Process `$(PKGDATA)'. + + * util/update-grub_lib.in (font_path): Search for *.pff files in + a few more locations, including `${pkgdata}'. + +2007-12-23 Robert Millan + + Patch from Bean : + * disk/loopback.c (grub_loopback_read): Add missing bit shift to + `size'. + +2007-12-21 Bean + + * conf/common.rmk (pkgdata_MODULES): Add ntfscomp.mod. + (ntfscomp_mod_SOURCES): New variable. + (ntfscomp_mod_CFLAGS): Likewise. + (ntfscomp_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfscomp.c. + (grub_probe_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * conf/i386-linuxbios.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfscomp.c. + (grub_emu_SOURCES): Likewise. + + * fs/ntfs.c (grub_ntfscomp_func): New variable. + (read_run_list): Renamed to grub_ntfs_read_run_list. + (decomp_nextvcn): Moved to ntfscomp.c. + (decomp_getch): Likewise. + (decomp_get16): Likewise. + (decomp_block): Likewise. + (read_block): Likewise. + (read_data): Partially moved to ntfscomp.c. + (fixup): Change unsigned to grub_uint16_t. + (read_mft): Change unsigned long to grub_uint32_t. + (read_attr): Likewise. + (read_data): Likewise. + (read_run_data): Likewise. + (read_run_list): Likewise. + (read_mft): Likewise. + + * fs/ntfscomp.c: New file. + + * include/grub/ntfs.h: New file. + +2007-12-16 Robert Millan + + * util/grub-mkdevicemap.c (make_device_map): Iterate up to 20 for + IDE disk check, since Linux is known to support 20 IDE disks. + Reported by Colin Watson. + +2007-12-15 Bean + + * conf/i386-pc.rmk (pkgdata_IMAGES): Add lnxboot.img. + (lnxboot_img_SOURCES): New variable. + (lnxboot_img_ASFLAGS): Likewise. + (lnxboot_img_LDFLAGS): Likewise. + + * boot/i386/pc/lnxboot.S: New file. + +2007-11-24 Pavel Roskin + + * configure.ac: Test if '--build-id=none' is supported by the + linker. If yes, add it to TARGET_LDFLAGS. Build ID causes + objcopy to generate incorrect binary files (binutils + 2.17.50.0.18-1 as shipped by Fedora 8). + * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when + linking, so that build ID doesn't break the test. + +2007-11-24 Pavel Roskin + + * include/grub/i386/time.h: use "void" in the argument list + of grub_cpu_idle(). + * include/grub/powerpc/time.h: Likewise. + * include/grub/sparc64/time.h: Likewise. + +2007-11-18 Christian Franke + + * util/console.c (grub_ncurses_getkey): Change curses KEY_* mapping, + now return control chars instead of GRUB_CONSOLE_KEY_* constants. + This fixes the problem that function keys did not work in grub-emu. + +2007-11-18 Christian Franke + + * disk/host.c (grub_host_open): Remove attribute unused from + name parameter. Add check for "host". This fixes the problem + that grub-emu does not find partitions. + +2007-11-18 Christian Franke + + * util/hostfs.c (is_dir): New function. + (grub_hostfs_dir): Handle missing dirent.d_type case. + (grub_hostfs_read): Add missing fseek(). + (grub_hostfs_label): Clear label pointer. This fixes a crash + of grub-emu on "ls (host)". + +2007-11-18 Christian Franke + + * include/grub/i386/pc/init.h (struct grub_machine_mmap_entry): + Add attribute packed, gcc 3.4.4 on Cygwin aligns this + to 64 bit boundary by default. + +2007-11-18 Bean + + * conf/common.rmk (pkgdata_MODULES): Add hexdump.mod. + (hexdump_mod_SOURCES): New variable. + (hexdump_mod_CFLAGS): Likewise. + (hexdump_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/i386-linuxbios.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add command/hexdump.c. + + * include/grub/hexdump.h: New file. + + * commands/hexdump.c: New file. + +2007-11-10 Robert Millan + + * commands/i386/pc/play.c (beep_off): Switch order of arguments + in grub_outb() calls. + (beep_on): Likewise. + +2007-11-10 Christian Franke + + * normal/menu.c (run_menu): Check for empty menu to avoid crash. + (grub_menu_run): Likewise. + +2007-11-10 Robert Millan + + * include/grub/i386/efi/machine.h: New file. + * include/grub/i386/linuxbios/machine.h: Likewise. + * include/grub/i386/pc/machine.h: Likewise. + * include/grub/powerpc/ieee1275/machine.h: Likewise. + * include/grub/sparc64/ieee1275/machine.h: Likewise. + + * term/i386/pc/serial.c: Include . + (serial_hw_io_addr): New variable. + (serial_hw_get_port): Obtain port address from `serial_hw_io_addr' + instead of `(unsigned short *) 0x400'. + +2007-11-10 Bean + + * fs/ntfs.c (read_block): Fix a bug caused by adjacent blocks. + +2007-11-10 Vesa Jaaskelainen + + * conf/i386-pc.rmk (pkgdata_MODULES): Added vga.mod. + (vga_mod_SOURCES): Added. + (vga_mod_CFLAGS): Likewise. + (vga_mod_LDFLAGS): Likewise. + + * term/i386/pc/vga.c (get_map_mask): Switch order of arguments in + grub_outb() calls. + (set_map_mask): Likewise. + (set_read_map): Likewise. + (set_read_address): Likewise. + (vga_font): Removed variable. + (get_vga_glyph): Removed function. + (invalidate_char): Likewise. + (write_char): Changed to use grub_font_get_glyph() for font + information. + (grub_vga_putchar): Likewise. + (grub_vga_getcharwidth): Likewise. + +2007-11-10 Vesa Jaaskelainen + + * conf/i386-pc.rmk (boot_img_LDFLAGS): Use COMMON_LDFLAGS for target + flags. + (pxeboot_img_LDFLAGS): Likewise. + (diskboot_img_LDFLAGS): Likewise. + (kernel_img_LDFLAGS): Likewise. + +2007-11-06 Robert Millan + + * term/i386/pc/serial.c (serial_hw_put): Switch order of arguments + in grub_outb() calls. + (serial_hw_init): Likewise. + +2007-11-05 Robert Millan + + * util/update-grub.in: Allow files in ${update_grub_dir} to contain + spaces. Skip non-regular files. + +2007-11-05 Robert Millan + + * kern/disk.c (grub_disk_firmware_fini) + (grub_disk_firmware_is_tainted): New variables. + + * include/grub/disk.h (grub_disk_firmware_fini) + (grub_disk_firmware_is_tainted): Likewise. + + * disk/i386/pc/biosdisk.c (GRUB_MOD_FINI(biosdisk)): Moved from here ... + (grub_disk_biosdisk_fini): ... to here. + (GRUB_MOD_FINI(biosdisk)): Implement using grub_disk_biosdisk_fini(). + (GRUB_MOD_INIT(biosdisk)): Abort when `grub_disk_firmware_is_tainted' + is set. Register grub_disk_biosdisk_fini() in + `grub_disk_firmware_fini'. + + * disk/ata.c: Remove `'. + (GRUB_MOD_INIT(ata)): Remove grub_biosdisk_fini() call. + Use `grub_disk_firmware_is_tainted' and `grub_disk_firmware_fini' + to finish existing firmware disk interface. + + * conf/i386-linuxbios.rmk (pkgdata_MODULES): Add `ata.mod'. + (ata_mod_SOURCES): New variable. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + +2007-11-05 Robert Millan + + * disk/ata.c: Remove `'. Include `'. + (grub_ata_wait): Reimplement using grub_millisleep(). + + * include/grub/misc.h (grub_div_roundup): Fix parenthesization. + * include/grub/i386/time.h (grub_cpu_idle): Disable `hlt' instruction. + +2007-11-03 Marco Gerards + + * term/i386/pc/vga_text.c: Include . + (CRTC_ADDR_PORT): New macro. + (CRTC_DATA_PORT): Likewise. + (CRTC_CURSOR): Likewise. + (CRTC_CURSOR_ADDR_HIGH): Likewise. + (CRTC_CURSOR_ADDR_LOW): Likewise. + (update_cursor): New function. + (grub_console_real_putchar): Call `update_cursor'. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Set the default color when clearing the + screen. + (grub_console_setcursor): Implemented. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_pio_read): Don't wait for the command to + become activate. + (grub_ata_pio_write): Likewise. + + (grub_atapi_identify): Wait after issuing an ATA command. + (grub_atapi_packet): Likewise. + (grub_ata_identify): Likewise. + (grub_ata_readwrite): Likewise. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_pio_read): Detect and return the error code. + (grub_ata_pio_write): Likewise. + (grub_ata_readwrite): Use `grub_error', instead of + returning `grub_errno'. + +2007-11-03 Marco Gerards + + * disk/ata.c (grub_ata_readwrite): Call grub_ata_pio_read and + grub_ata_pio_write once for every single sector, instead of for + multiple sectors. + +2007-10-31 Robert Millan + + * configure.ac: Add `i386-linuxbios' to the list of supported targets. + + * conf/i386-linuxbios.rmk: New file. + + * kern/i386/pc/hardware.c: Likewise. + * term/i386/pc/at_keyboard.c: Likewise. + * term/i386/pc/vga_text.c: Likewise. + + * include/grub/i386/linuxbios/boot.h: Likewise. + * include/grub/i386/linuxbios/console.h: Likewise. + * include/grub/i386/linuxbios/init.h: Likewise. + * include/grub/i386/linuxbios/kernel.h: Likewise. + * include/grub/i386/linuxbios/loader.h: Likewise. + * include/grub/i386/linuxbios/memory.h: Likewise. + * include/grub/i386/linuxbios/serial.h: Likewise. + * include/grub/i386/linuxbios/time.h: Likewise. + + * kern/i386/linuxbios/init.c: Likewise. + * kern/i386/linuxbios/startup.S: Likewise. + * kern/i386/linuxbios/table.c: Likewise. + +2007-10-31 Marco Gerards + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `ata.mod'. + (ata_mod_SOURCES): New variable. + (ata_mod_CFLAGS): Likewise. + (ata_mod_LDFLAGS): Likewise. + + * disk/ata.c: New file. + + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEV_ATA_ID'. + +2007-10-31 Robert Millan + + * include/grub/i386/pc/init.h (grub_lower_mem): Moved from here ... + * include/grub/i386/pc/memory.h (grub_lower_mem): ... to here. + + * include/grub/i386/pc/init.h (grub_upper_mem): Moved from here ... + * include/grub/i386/pc/memory.h (grub_upper_mem): ... to here. + + * include/grub/i386/pc/memory.h: Include `' and + `'. + + * loader/i386/pc/multiboot.c: Include `'. + +2007-10-27 Robert Millan + + * include/grub/types.h (ULONG_MAX): Define macro. + +2007-10-22 Robert Millan + + * kern/i386/pc/startup.S: Remove `"kern/i386/realmode.S"'. Include + `"../realmode.S"'. + Remove `"kern/i386/loader.S"'. Include `"../loader.S"'. + +2007-10-22 Robert Millan + + * conf/i386-pc.rmk (kernel_img_SOURCES): Remove `disk/i386/pc/biosdisk.c'. + (pkgdata_MODULES): Add `biosdisk.mod'. + (biosdisk_mod_SOURCES, biosdisk_mod_CFLAGS, biosdisk_mod_LDFLAGS): New + variables. + + * disk/i386/pc/biosdisk.c: Include `'. + (grub_biosdisk_init): Replace with ... + (GRUB_MOD_INIT(biosdisk)): ... this. + (grub_biosdisk_fini): Replace with ... + (GRUB_MOD_FINI(biosdisk)): ... this. + + * kern/i386/pc/init.c: Remove `'. + (grub_machine_init): Remove call to grub_biosdisk_init(). + (grub_machine_fini): Remove call to grub_machine_fini(). + + * util/i386/pc/grub-install.in (modules): Add `biosdisk'. + +2007-10-22 Robert Millan + + * include/grub/time.h: New file. + * include/grub/i386/time.h: Likewise. + * include/grub/powerpc/time.h: Likewise. + * include/grub/sparc64/time.h: Likewise. + + * include/grub/i386/pc/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + * include/grub/powerpc/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + * include/grub/sparc64/ieee1275/time.h (KERNEL_TIME_HEADER): Rename all + instances to ... + (KERNEL_MACHINE_TIME_HEADER): ... this. + + * kern/i386/efi/init.c: Include `'. + (grub_millisleep): New function. + * kern/i386/pc/init.c: Include `'. + (grub_millisleep): New function. + * kern/powerpc/ieee1275/init.c: Include `'. + Remove `grub/machine/time.h' include. + (grub_millisleep): New function. + * kern/sparc64/ieee1275/init.c: Include `'. + Remove `grub/machine/time.h' include. + (grub_millisleep): New function. + + * include/grub/misc.h (grub_div_roundup): New function. + + * kern/misc.c: Include `'. + (grub_millisleep_generic): New function. + + * conf/i386-efi.rmk (kernel_mod_HEADERS): Remove `i386/efi/time.h'. + Add `time.h'. + * conf/i386-pc.rmk (kernel_img_HEADERS): Remove `machine/time.h'. + Add `time.h'. + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Remove + `machine/time.h'. Add `time.h'. + * conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + +2007-10-21 Robert Millan + + * include/grub/misc.h (grub_max): New function. + +2007-10-21 Robert Millan + + * util/misc.c (grub_util_info): Call fflush() before returning. + +2007-10-20 Robert Millan + + * genmk.rb (Image): Copy `extra_flags' from here ... + (PModule): ... to here. Use it in `#{obj}: #{src}' rule. + + * commands/i386/cpuid.c (grub_cmd_cpuid): Add __attribute__ ((unused)) + to `argc' and `args' arguments. + +2007-10-17 Robert Millan + + * kern/i386/loader.S: New file. + + * kern/i386/pc/startup.S (grub_linux_prot_size): Moved from here ... + * kern/i386/loader.S (grub_linux_prot_size)... to here. + * kern/i386/pc/startup.S (grub_linux_tmp_addr): Moved from here ... + * kern/i386/loader.S (grub_linux_tmp_addr)... to here. + * kern/i386/pc/startup.S (grub_linux_real_addr): Moved from here ... + * kern/i386/loader.S (grub_linux_real_addr)... to here. + * kern/i386/pc/startup.S (grub_linux_boot_zimage): Moved from here ... + * kern/i386/loader.S (grub_linux_boot_zimage)... to here. + * kern/i386/pc/startup.S (grub_linux_boot_bzimage): Moved from here ... + * kern/i386/loader.S (grub_linux_boot_bzimage)... to here. + * kern/i386/pc/startup.S (grub_multiboot_real_boot): Moved from here ... + * kern/i386/loader.S (grub_multiboot_real_boot)... to here. + * kern/i386/pc/startup.S (grub_multiboot2_real_boot): Moved from here ... + * kern/i386/loader.S (grub_multiboot2_real_boot)... to here. + + * kern/i386/realmode.S: New file. + + * kern/i386/pc/startup.S (protstack): Moved from here ... + * kern/i386/realmode.S (protstack)... to here. + * kern/i386/pc/startup.S (gdt): Moved from here ... + * kern/i386/realmode.S (gdt)... to here. + * kern/i386/pc/startup.S (prot_to_real): Moved from here ... + * kern/i386/realmode.S (prot_to_real)... to here. + + * kern/i386/pc/startup.S: Include `kern/i386/loader.S' and + `kern/i386/realmode.S'. + +2007-10-17 Robert Millan + + * include/grub/i386/loader.h: New file. + + * include/grub/i386/pc/loader.h (grub_linux_prot_size) + (grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr) + (grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage) + (grub_multiboot_real_boot, grub_multiboot2_real_boot) + (grub_rescue_cmd_linux, grub_rescue_cmd_initrd): Moved from here ... + * include/grub/i386/loader.h (grub_linux_prot_size) + (grub_linux_tmp_addr, grub_linux_real_addr, grub_os_area_addr) + (grub_os_area_size, grub_linux_boot_zimage, grub_linux_boot_bzimage) + (grub_multiboot_real_boot, grub_multiboot2_real_boot) + (grub_rescue_cmd_linux, grub_rescue_cmd_initrd): ... to here. + + * include/grub/i386/pc/loader.h: Include `grub/cpu/loader.h'. + +2007-10-15 Robert Millan + + * normal/misc.c (grub_normal_print_device_info): Do not probe for + filesystem when dev->disk is unset. + Do probe for filesystem even when dev->disk->has_partitions is set. + In case a filesystem is found, always report it. + In case it isn't, if dev->disk->has_partitions is set, report that + a partition table was found instead of reporting that no filesystem + could be identified. + +2007-10-12 Robert Millan + + * conf/powerpc-ieee1275.rmk (grub_mkimage_SOURCES): Replace reference + to util/powerpc/ieee1275/grub-mkimage.c with util/elf/grub-mkimage.c. + + * include/grub/types.h (grub_host_to_target16): New macro. + (grub_host_to_target32): Likewise. + (grub_host_to_target64): Likewise. + (grub_target_to_host16): Likewise. + (grub_target_to_host32): Likewise. + (grub_target_to_host64): Likewise. + + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN): + Renamed from to ... + (GRUB_MOD_ALIGN): ...this. Update all users. + + * util/elf/grub-mkimage.c (load_note): Replace grub_cpu_to_be32 with + grub_host_to_target32. + Replace grub_be_to_cpu32 with grub_target_to_host32. + (load_modules): Likewise. + (add_segments): Replace grub_be_to_cpu16 with grub_target_to_host16. + Replace grub_be_to_cpu32 with grub_target_to_host32. + Replace grub_cpu_to_be16 with grub_host_to_target16. + Replace grub_cpu_to_be32 grub_host_to_target32. + +2007-10-12 Robert Millan + + * util/powerpc/ieee1275/grub-mkimage.c: Moved to ... + * util/elf/grub-mkimage.c: ... here. + + * DISTLIST: Add `util/elf/grub-mkimage.c'. Remove + `util/powerpc/ieee1275/grub-mkimage.c'. + +2007-10-07 Robert Millan + + * kern/powerpc/ieee1275/init.c: Rename HEAP_LIMIT to HEAP_MAX_ADDR, + and make it easier to figure out. + Add HEAP_MIN_SIZE and HEAP_MAX_ADDR definitions. + (grub_claim_heap): Use HEAP_MAX_ADDR rather than taking a parameter. + Do not avoid claiming a region above HEAP_MAX_ADDR if that would + leave us with less than HEAP_MIN_SIZE total heap. + Avoid our total amount of heap to surpass HEAP_MAX_SIZE. + +2007-10-03 Robert Millan + + * include/grub/i386/io.h: New file. + * commands/i386/pc/play.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + * term/i386/pc/serial.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + * term/i386/pc/vga.c (inb): Removed. + (outb): Removed. + Include grub/cpu/io.h. Replace inb() with grub_inb() and outb() + with grub_outb(). + +2007-10-02 Robert Millan + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add util/hostfs.c. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + Reported by Marcin Kurek. + +2007-09-07 Robert Millan + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_test_flag): Detect + SmartFirmware version updates (as released by Sven Luther), and avoid + setting GRUB_IEEE1275_FLAG_NO_PARTITION_0 or + GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS unless the running version is + known broken. + +2007-09-03 Yoshinori K. Okuji + + From Hitoshi Ozeki: + * kern/i386/pc/init.c (compact_mem_regions): Decrease NUM_REGIONS + when merging two regions. + +2007-09-03 Yoshinori K. Okuji + + * kern/rescue.c (grub_enter_rescue_mode): Free ARGS. + * normal/completion.c (grub_normal_do_completion): Likewise. + Reported by Hitoshi Ozeki. + +2007-09-03 Yoshinori K. Okuji + + Do not use devices at boot in chainloading. + + * loader/i386/pc/chainloader.c (boot_drive): New variable. + (boot_part_addr): Likewise. + (grub_chainloader_boot): Simply call grub_chainloader_real_boot + with BOOT_DRIVE and BOOT_PART_ADDR. + (grub_chainloader_cmd): Set BOOT_DRIVE and BOOT_PART_ADDR. + Reported by Hitoshi Ozeki . + +2007-08-29 Robert Millan + + Patch from Simon Peter : + * genmk.rb (Utility): Append $(#{src}_DEPENDENCIES) to #{obj} targets. + * conf/i386-pc.rmk: Replace grub-probe_DEPENDENCIES with + util/grub-probe.c_DEPENDENCIES. Replace grub-setup_DEPENDENCIES with + util/i386/pc/grub-setup.c_DEPENDENCIES. + * conf/i386-efi.rmk: Replace grub-probe_DEPENDENCIES with + util/grub-probe.c_DEPENDENCIES. + * conf/powerpc-ieee1275.rmk: Likewise. + +2007-08-28 Robert Millan + + * util/i386/get_disk_name.c: New. Implement grub_util_get_disk_name() + to tell grub-mkdevicemap how to name devices. + * util/ieee1275/get_disk_name.c: Likewise (using "ofpathname -a" + feature). + + * conf/i386-efi.rmk (grub_mkdevicemap_SOURCES): Add + util/i386/get_disk_name.c. + * conf/i386-pc.rmk (grub_mkdevicemap_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_mkdevicemap_SOURCES): Add + util/ieee1275/get_disk_name.c. + + * include/grub/util/misc.h: grub_util_get_disk_name() declaration. + + * DISTLIST: Add util/i386/get_disk_name.c and + util/ieee1275/get_disk_name.c. + + * util/grub-mkdevicemap.c: Replace device naming logic with + grub_util_get_disk_name() calls. + +2007-08-20 Robert Millan + + * normal/menu.c (run_menu): Refer to seconds as "s" not "seconds" + (so that it works for both plural and singular quantities). + +2007-08-05 Robert Millan + + * util/grub.d/10_linux.in (test_gt): Strip out vmlinu[xz]- prefix + so that [xz] isn't taken into account when determining order. + +2007-08-02 Marco Gerards + + * DISTLIST: Add `disk/host.c', `fs/ntfs.c', `include/multiboot.h', + `include/multiboot2.h', `include/grub/elfload.h', + `include/multiboot.h', `include/grub/multiboot.h', + `include/grub/multiboot_loader.h', `include/grub/multiboot2.h', + `include/grub/i386/pc/biosdisk.h', `include/grub/util/biosdisk.h', + `kern/elf.c', `loader/multiboot_loader.c', + `loader/multiboot_loader_normal.c', `loader/multiboot2.c', + `loader/i386/pc/multiboot2.c', + `loader/powerpc/ieee1275/multiboot2.c', `util/hostfs.c' and + `util/i386/pc/grub-mkrescue.in'. Remove + `include/grub/biosdisk.h', `include/grub/i386/pc/multiboot.h', + `include/grub/i386/pc/util/biosdisk.h' and + `include/grub/powerpc/ieee1275/multiboot.h'. + +2007-08-02 Bean + + * conf/common.rmk (pkgdata_MODULES): Add ntfs.mod. + (ntfs_mod_SOURCES): New variable. + (ntfs_mod_CFLAGS): Likewise. + (ntfs_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ntfs.c. + (grub_probe_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add fs/ntfs.c. + (grub_emu_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add fs/ntfs.c. + (grub_emu_SOURCES): Likewise. + + * conf/misc.c (grub_utf16_to_utf8): Fix unicode conversion bug. + + * fs/ntfs.c: New file. + +2007-08-02 Bean + + * disk.h (grub_disk): Use NESTED_FUNC_ATTR. + + * file.h (grub_file): Likewise. + + * fshelp.h (grub_fshelp_read_file): Likewise. + + * util/i386/pc/grub-setup.c (setup): Likewise. + (save_first_sector): Likewise. + (save_blocklists): Likewise. + + * fs/affs.c (grub_affs_read_file): Likewise. + + * fs/ext2.c (grub_ext2_read_file): Likewise. + + * fs/fat.c (grub_fat_read_data): Likewise. + + * fs/fshelp.c (grub_fshelp_read_file): Likewise. + + * fs/hfs.c (grub_hfs_read_file): Likewise. + + * fs/hfsplus.c (grub_hfsplus_read_file): Likewise. + + * fs/jfs.c (grub_jfs_read_file): Likewise. + + * fs/minix.c (grub_minix_read_file): Likewise. + + * fs/sfs.c (grub_sfs_read_file): Likewise. + + * fs/ufs.c (grub_ufs_read_file): Likewise. + + * fs/xfs.c (grub_xfs_read_file): Likewise. + + * command/blocklist.c (read_blocklist): Likewise. + (print_blocklist): Likewise. + +2007-08-02 Marco Gerards + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/host.c' and + `util/hostfs.c'. + + * disk/host.c: New file. + + * util/hostfs.c: Likewise. + + * fs/hfsplus.c (grub_hfsplus_mount): When reading out of disk, + return `GRUB_ERR_BAD_FS'. + * fs/sfs.c (grub_sfs_mount): Likewise. + * fs/xfs.c (grub_xfs_mount): Likewise. + + * include/grub/disk.h (enum grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_HOST_ID'. + + * util/grub-emu.c (main): Initialize and de-initialize hostfs. + +2007-07-24 Jerone Young + + * conf/i386-pc.rmk: Add Multiboot loader and multiboot 2 to multiboot + modules for compilation. + * conf/powerpc-ieee1275.rmk: Likewise. + + * include/multiboot.h: Move multiboot definitions to one file. Rename + many definitions to not get grub specific. + * include/multiboot2.h: Create header with multiboot 2 definitions. + * include/grub/multiboot.h: Header for grub specific function + prototypes and definitions. + * include/grub/multiboot2.h: Likewise. + * include/grub/multiboot_loader.h: Likewise. + * include/grub/i386/pc/multiboot.h: Removed. + * include/grub/powerpc/ieee1275/multiboot.h: Removed. + + * loader/multiboot_loader.c: Created to act as a proxy for multiboot 1 + and 2 to allow for one multiboot and module commands. + * loader/multiboot2.c: Add multiboot2 functionality. + * loader/i386/pc/multiboot.c: Modify for new multiboot header location + and definition names. + * loader/i386/pc/multiboot2.c: Created to add i386 specific multiboot + 2 functions. + * loader/powerpc/ieee1275/multiboot2.c: Created to add powerpc + ieee1275 specific multiboot2 code. + + * kern/i386/pc/startup.S: Change headers and definition names for + multiboot. Add function grub_multiboot2_real_boot for multiboot 2. + +2007-07-22 Robert Millan + + * geninitheader.sh: Process file specified in first parameter rather + than hardcoding grub_modules_init.lst. + * geninit.sh: Likewise. Also, construct header name dynamically rather + than hardcoding grub_modules_init.h. + + * conf/common.rmk: Rename grub_modules_init.[ch] files associated with + grub-emu to grub_emu_init.[ch]. Add rules to build analogous + grub_probe_init.[ch] and grub_setup_init.[ch]. + + * conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Replace + grub_modules_init.h with grub_emu_init.h. + (grub_probe_DEPENDENCIES, grub_probe_SOURCES): Add new + grub_probe_init.[ch] files. + * conf/i386-efi.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + (grub_setup_DEPENDENCIES, grub_setup_SOURCES): Add new + grub_setup_init.[ch] files. + + * util/grub-emu.c: Replace grub_modules_init.h with grub_emu_init.h. + * util/grub-probe.c: Include grub_probe_init.h. Use grub_init_all() + to initialize modules rather than a list of hardcoded functions. + * util/i386/pc/grub-setup.c: Include grub_setup_init.h. Use + grub_init_all() to initialize modules rather than a list of hardcoded + functions. + +2007-07-22 Robert Millan + + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_NO_PARTITION_0 flag when running on SmartFirmware. + +2007-07-22 Robert Millan + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): Add + GRUB_IEEE1275_FLAG_BROKEN_OUTPUT flag. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): Set this + flag when running on SmartFirmware. + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Avoid running + "output-device output" command when GRUB_IEEE1275_FLAG_BROKEN_OUTPUT + was set. + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Increase partno when GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS flag is set, + rather than decreasing it. + + * util/i386/pc/grub-setup.c (setup): When embedding is required, but + there's not enough space to do it, fail in the same way as when it + can't be done because there are no partitions. + + * util/powerpc/ieee1275/grub-install.in: Improve error message shown + when nvsetenv failed. + +2007-07-22 Yoshinori K. Okuji + + * conf/i386-pc.rmk (CLEANFILES): Removed for grub-mkrescue, + because this rule is automatically generated. + (grub-mkrescue): Removed for the same reason as above. + +2007-07-22 Yoshinori K. Okuji + + Migrate to GNU General Public License Version 3. + + * COPYING: Replaced with the plain text version of GPLv3. + + * config.guess: Updated from gnulib. + * config.sub: Likewise. + + * geninit.sh: Output a GPLv3 copyright notice. + * geninitheader.sh: Likewise. + * genmodsrc.sh: Likewise. + * gensymlist.sh.in: Likewise. + + * boot/i386/pc/boot.S: Upgraded to GPLv3. + * boot/i386/pc/diskboot.S: Likewise. + * boot/i386/pc/pxeboot.S: Likewise. + * commands/blocklist.c: Likewise. + * commands/boot.c: Likewise. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/configfile.c: Likewise. + * commands/echo.c: Likewise. + * commands/help.c: Likewise. + * commands/ls.c: Likewise. + * commands/search.c: Likewise. + * commands/terminal.c: Likewise. + * commands/test.c: Likewise. + * commands/videotest.c: Likewise. + * commands/i386/cpuid.c: Likewise. + * commands/i386/pc/halt.c: Likewise. + * commands/i386/pc/play.c: Likewise. + * commands/i386/pc/reboot.c: Likewise. + * commands/i386/pc/vbeinfo.c: Likewise. + * commands/i386/pc/vbetest.c: Likewise. + * commands/ieee1275/halt.c: Likewise. + * commands/ieee1275/reboot.c: Likewise. + * commands/ieee1275/suspend.c: Likewise. + * disk/loopback.c: Likewise. + * disk/lvm.c: Likewise. + * disk/raid.c: Likewise. + * disk/efi/efidisk.c: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * font/manager.c: Likewise. + * fs/affs.c: Likewise. + * fs/ext2.c: Likewise. + * fs/fat.c: Likewise. + * fs/fshelp.c: Likewise. + * fs/hfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/sfs.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * hello/hello.c: Likewise. + * include/grub/acorn_filecore.h: Likewise. + * include/grub/arg.h: Likewise. + * include/grub/bitmap.h: Likewise. + * include/grub/boot.h: Likewise. + * include/grub/cache.h: Likewise. + * include/grub/device.h: Likewise. + * include/grub/disk.h: Likewise. + * include/grub/dl.h: Likewise. + * include/grub/elfload.h: Likewise. + * include/grub/env.h: Likewise. + * include/grub/err.h: Likewise. + * include/grub/file.h: Likewise. + * include/grub/font.h: Likewise. + * include/grub/fs.h: Likewise. + * include/grub/fshelp.h: Likewise. + * include/grub/gzio.h: Likewise. + * include/grub/hfs.h: Likewise. + * include/grub/kernel.h: Likewise. + * include/grub/loader.h: Likewise. + * include/grub/lvm.h: Likewise. + * include/grub/misc.h: Likewise. + * include/grub/mm.h: Likewise. + * include/grub/net.h: Likewise. + * include/grub/normal.h: Likewise. + * include/grub/parser.h: Likewise. + * include/grub/partition.h: Likewise. + * include/grub/pc_partition.h: Likewise. + * include/grub/raid.h: Likewise. + * include/grub/rescue.h: Likewise. + * include/grub/script.h: Likewise. + * include/grub/setjmp.h: Likewise. + * include/grub/symbol.h: Likewise. + * include/grub/term.h: Likewise. + * include/grub/terminfo.h: Likewise. + * include/grub/tparm.h: Likewise. + * include/grub/types.h: Likewise. + * include/grub/video.h: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/chainloader.h: Likewise. + * include/grub/efi/console.h: Likewise. + * include/grub/efi/console_control.h: Likewise. + * include/grub/efi/disk.h: Likewise. + * include/grub/efi/efi.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/efi/time.h: Likewise. + * include/grub/i386/linux.h: Likewise. + * include/grub/i386/setjmp.h: Likewise. + * include/grub/i386/types.h: Likewise. + * include/grub/i386/efi/kernel.h: Likewise. + * include/grub/i386/efi/loader.h: Likewise. + * include/grub/i386/efi/time.h: Likewise. + * include/grub/i386/pc/biosdisk.h: Likewise. + * include/grub/i386/pc/boot.h: Likewise. + * include/grub/i386/pc/chainloader.h: Likewise. + * include/grub/i386/pc/console.h: Likewise. + * include/grub/i386/pc/init.h: Likewise. + * include/grub/i386/pc/kernel.h: Likewise. + * include/grub/i386/pc/loader.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * include/grub/i386/pc/multiboot.h: Likewise. + * include/grub/i386/pc/serial.h: Likewise. + * include/grub/i386/pc/time.h: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * include/grub/i386/pc/vbeblit.h: Likewise. + * include/grub/i386/pc/vbefill.h: Likewise. + * include/grub/i386/pc/vbeutil.h: Likewise. + * include/grub/i386/pc/vga.h: Likewise. + * include/grub/ieee1275/ieee1275.h: Likewise. + * include/grub/ieee1275/ofdisk.h: Likewise. + * include/grub/powerpc/libgcc.h: Likewise. + * include/grub/powerpc/setjmp.h: Likewise. + * include/grub/powerpc/types.h: Likewise. + * include/grub/powerpc/ieee1275/biosdisk.h: Likewise. + * include/grub/powerpc/ieee1275/console.h: Likewise. + * include/grub/powerpc/ieee1275/ieee1275.h: Likewise. + * include/grub/powerpc/ieee1275/kernel.h: Likewise. + * include/grub/powerpc/ieee1275/loader.h: Likewise. + * include/grub/powerpc/ieee1275/multiboot.h: Likewise. + * include/grub/powerpc/ieee1275/time.h: Likewise. + * include/grub/powerpc/ieee1275/util/biosdisk.h: Likewise. + * include/grub/sparc64/libgcc.h: Likewise. + * include/grub/sparc64/setjmp.h: Likewise. + * include/grub/sparc64/types.h: Likewise. + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/sparc64/ieee1275/ieee1275.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/time.h: Likewise. + * include/grub/util/biosdisk.h: Likewise. + * include/grub/util/getroot.h: Likewise. + * include/grub/util/lvm.h: Likewise. + * include/grub/util/misc.h: Likewise. + * include/grub/util/raid.h: Likewise. + * include/grub/util/resolve.h: Likewise. + * io/gzio.c: Likewise. + * kern/device.c: Likewise. + * kern/disk.c: Likewise. + * kern/dl.c: Likewise. + * kern/elf.c: Likewise. + * kern/env.c: Likewise. + * kern/err.c: Likewise. + * kern/file.c: Likewise. + * kern/fs.c: Likewise. + * kern/loader.c: Likewise. + * kern/main.c: Likewise. + * kern/misc.c: Likewise. + * kern/mm.c: Likewise. + * kern/parser.c: Likewise. + * kern/partition.c: Likewise. + * kern/rescue.c: Likewise. + * kern/term.c: Likewise. + * kern/efi/efi.c: Likewise. + * kern/efi/init.c: Likewise. + * kern/efi/mm.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/efi/init.c: Likewise. + * kern/i386/efi/startup.S: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/lzo1x.S: Likewise. + * kern/i386/pc/startup.S: Likewise. + * kern/ieee1275/ieee1275.c: Likewise. + * kern/powerpc/cache.S: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/powerpc/ieee1275/cmain.c: Likewise. + * kern/powerpc/ieee1275/crt0.S: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * kern/sparc64/cache.S: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/sparc64/ieee1275/openfw.c: Likewise. + * loader/efi/chainloader.c: Likewise. + * loader/efi/chainloader_normal.c: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/efi/linux_normal.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/chainloader_normal.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/linux_normal.c: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * loader/i386/pc/multiboot_normal.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/powerpc/ieee1275/linux_normal.c: Likewise. + * normal/arg.c: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/completion.c: Likewise. + * normal/execute.c: Likewise. + * normal/function.c: Likewise. + * normal/lexer.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/menu_entry.c: Likewise. + * normal/misc.c: Likewise. + * normal/parser.y: Likewise. + * normal/script.c: Likewise. + * normal/i386/setjmp.S: Likewise. + * normal/powerpc/setjmp.S: Likewise. + * normal/sparc64/setjmp.S: Likewise. + * partmap/acorn.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/gpt.c: Likewise. + * partmap/pc.c: Likewise. + * partmap/sun.c: Likewise. + * term/gfxterm.c: Likewise. + * term/terminfo.c: Likewise. + * term/efi/console.c: Likewise. + * term/i386/pc/console.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * util/biosdisk.c: Likewise. + * util/console.c: Likewise. + * util/genmoddep.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-emu.c: Likewise. + * util/grub-mkdevicemap.c: Likewise. + * util/grub-probe.c: Likewise. + * util/lvm.c: Likewise. + * util/misc.c: Likewise. + * util/raid.c: Likewise. + * util/resolve.c: Likewise. + * util/update-grub.in: Likewise. + * util/update-grub_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + * util/i386/efi/grub-install.in: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + * util/i386/pc/grub-install.in: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/i386/pc/grub-mkrescue.in: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/misc.c: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-mkimage.c: Likewise. + * util/powerpc/ieee1275/misc.c: Likewise. + * video/bitmap.c: Likewise. + * video/video.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * video/i386/pc/vbeblit.c: Likewise. + * video/i386/pc/vbefill.c: Likewise. + * video/i386/pc/vbeutil.c: Likewise. + * video/readers/tga.c: Likewise. + +2007-07-02 Robert Millan + + * conf/i386-efi.rmk: Replace obsolete reference to + util/i386/pc/biosdisk.c with util/biosdisk.c, and util/i386/pc/getroot.c + with util/getroot.c. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + + * util/grub-emu.c (main): Fix unchecked pointer handling. + +2007-07-02 Robert Millan + + * util/i386/efi/grub-install.in: Allow `grub_probe --target=partmap' + invocation to fail, in order to support partition-less media. + + * util/i386/pc/grub-install.in: Likewise. + + * util/powerpc/ieee1275/grub-install.in: Use grub-probe to determine + which fs or partmap modules are needed (akin to its sister scripts). + + Also use grub-probe to get rid of unportable /proc/mounts check. + + Print the same informational message that the other scripts do, before + exiting. + +2007-06-23 Robert Millan + + * util/update-grub_lib.in (font_path): New function. Determine whether + a font file can be found and, if so, echo the GRUB path to it. + + * util/update-grub.in: Handle multiple terminals depending on user + input, platform availability and font file presence. Propagate + variables of our findings to /etc/grub.d/ children. + + * util/grub.d/00_header.in: Handle multiple terminals, based on + environment setup by update-grub. + +2007-06-23 Robert Millan + + * conf/i386-pc.rmk (pkgdata_MODULES): Add serial.mod. + +2007-06-21 Robert Millan + + * include/grub/i386/pc/kernel.h: Define GRUB_KERNEL_MACHINE_DATA_END to + indicate end of data section in kernel image. + * include/grub/i386/efi/kernel.h: Define GRUB_KERNEL_MACHINE_PREFIX and + GRUB_KERNEL_MACHINE_DATA_END. + + * kern/i386/pc/startup.S: Do not initialize grub_prefix, only reserve + space for it. + * kern/i386/efi/startup.S: Likewise. + + * util/i386/pc/grub-mkimage.c: Initialize grub_prefix to /boot/grub + during image generation. Implement --prefix option to override this + patch. + * util/i386/efi/grub-mkimage.c: Likewise. + + * util/update-grub_lib.in (convert_system_path_to_grub_path): Split + code to make path relative to its root into a separate function. + + * util/i386/pc/grub-install.in: Use newly provided + make_system_path_relative_to_its_root() to convert ${grubdir}, then + pass the result to grub-install --prefix. + +2007-06-13 Robert Millan + + * include/grub/util/misc.h: Define DEFAULT_DIRECTORY and + DEFAULT_DEVICE_MAP. + * util/grub-emu.c: Use above definitions from misc.h instead of + defining them. + * util/grub-mkdevicemap.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/grub-probe.c: Likewise. + (probe): Abort with grub_util_error() when either + grub_guess_root_device or grub_util_get_grub_dev fails. + +2007-06-12 Robert Millan + + * normal/command.c (grub_command_execute): Use NULL rather than 0 for + "pager" assignment. + * util/biosdisk.c (grub_util_biosdisk_get_grub_dev): Likewise for + "pcdata". + * util/grub-probe.c (probe): Likewise for "drive_name". + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Pad both floppy images with zeroes, + not just the cdrom one. + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: Add "set -e". + Add --pkglibdir=DIR option to override pkglibdir. + Mention --image-type=TYPE in help output. + Fix --grub-mkimage (it was a no-op). + Abort gracefully when no parameter is given. + +2007-06-11 Robert Millan + + * util/i386/pc/grub-mkrescue.in: New file. + * conf/i386-pc.rmk: Add its build declarations. Put it in bin_SCRIPTS. + * Makefile.in: Handle bin_SCRIPTS. + +2007-06-10 Vesa Jaaskelainen + + * term/gfxterm.c (grub_gfxterm_init): Added support for specifying + list of video modes. + +2007-06-06 Robert Millan + + * util/update-grub_lib.in (convert_system_path_to_grub_path): Abort if + file doesn't exist, or if it is in a filesystem grub can't read. + + * util/update-grub.in: Set fallback for GRUB_FS check to "unknown". Do + not abort if GRUB_DRIVE could not be defined. Rearrange generated + header comment to fit in 80 columns when the variables are resolved. + + * util/grub.d/00_header.in: Only set root variable when GRUB_DRIVE + could be identified by update-grub. Remove redundant check for + unifont.pff existence (since convert_system_path_to_grub_path now + handles that). + +2007-06-04 Robert Millan + + * conf/i386-efi.rmk (grub_probe_SOURCES): Add partmap/apple.c. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_probe_SOURCES): Add partmap/pc.c. + +2007-06-04 Robert Millan + + * conf/powerpc-ieee1275.rmk: Enable grub-mkdevicemap and grub-probe. + + * include/grub/partition.h: Declare grub_apple_partition_map_init and + grub_apple_partition_map_fini. + + * util/biosdisk.c + (grub_util_biosdisk_open): Replace BLKGETSIZE with BLKGETSIZE64 (needed + to access >2 TiB disks). + + Print disk->total_sectors with %llu instead of %lu, since this + variable is always 64-bit (prevents wrong disk size from being displayed + on either >2 TiB disk or big-endian CPU). + + (grub_util_biosdisk_get_grub_dev): Convert gpt_partition_map handling + into a generic case that supports all (sane) partition maps. + + Stop using grub_cpu_to_le32() on dos_part / bsd_part since it actually + breaks big-endian. + + * util/grub-probe.c: Call grub_apple_partition_map_init() before probe() + and grub_apple_partition_map_fini() after that. + +2007-06-01 Robert Millan + + * util/update-grub.in: Export GRUB_CMDLINE_LINUX. + + * util/grub.d/00_header.in: Only enable gfxterm when + convert_system_path_to_grub_path() succeeds. + +2007-05-20 Robert Millan + + * util/update-grub_lib.in: New file. + * DISTLIST: Add update-grub_lib.in. + * conf/common.rmk: Generate update-grub_lib and install it in + $(lib_DATA). + * Makefile.in: Add install routine for $(lib_DATA). + + * util/grub.d/00_header.in: Use convert_system_path_to_grub_path() + function provided by update-grub_lib to support arbitrary paths of + unifont.pff. + * util/update-grub.in: Use convert_system_path_to_grub_path() to + initialize GRUB_DRIVE_BOOT and GRUB_DRIVE_BOOT_GRUB variables. + +2007-05-19 Robert Millan + + * commands/i386/cpuid.c: New module. + * DISTLIST: Add it. + * conf/i386-efi.rmk: Enable cpuid.mod. + * conf/i386-pc.rmk: Likewise. + +2007-05-18 Jeroen Dekkers + + * kern/disk.c (grub_disk_read): Check return value of + grub_realloc(). + +2007-05-18 Jeroen Dekkers + + * util/getroot.c (grub_util_get_grub_dev): Support partitionable + arrays. + * disk/raid.c (grub_raid_open): Likewise. + +2007-05-17 Jeroen Dekkers + + * util/biosdisk.c (linux_find_partition): Allocate real_dev on the + stack instead of on the heap. + + * kern/disk.c (grub_disk_read): Make sure tmp_buf is big enough + before doing a read on it. + + * configure.ac: Only use -fno-stack-protector for the target + environment. + +2007-05-17 Jeroen Dekkers + + * video/i386/pc/vbe.c (grub_video_vbe_create_render_target): Add + __attribute_ ((unused)) to mode_type argument. + + * util/getroot.c (grub_guess_root_device): Fix #endif. + + * kern/misc.c (memcmp): Fix prototype. + + * include/grub/partition.h [GRUB_UTIL] + (grub_gpt_partition_map_init): Add prototype. + (grub_gpt_partition_map_fini): Likewise. + + * fs/jfs.c (struct grub_jfs_inode): Put __attribute__ ((packed) + at the right place. + + * fs/fat.c (grub_fat_mount): Replace ~0UL with ~0U. + (grub_fat_read_data): Likewise. + (grub_fat_find_dir): Likewise. + + * font/manager.c (find_glyph): Make table a const. + (grub_font_get_glyph): Remove bitmap from if statement. + +2007-05-16 Jeroen Dekkers + + * util/getroot.c (grub_guess_root_device): Remove RAID and LVM + code, first search for device in /dev/mapper, then in /dev. + (grub_util_get_grub_dev): New function. + * include/grub/util/getroot.h (grub_util_get_grub_dev): Add + prototype. + * util/grub-probe.c (probe): Remove check for RAID, call + grub_util_get_grub_dev() instead of + grub_util_biosdisk_get_grub_dev(). + * util/grub-emu.c (main): Call grub_util_get_grub_dev() instead of + grub_util_biosdisk_get_grub_dev(). + * util/i386/pc/grub-setup.c (main): Likewise. + +2007-05-16 Robert Millan + + * DISTLIST: Update for the latest changes. + * conf/i386-pc.rmk: Use the new paths for util/getroot.c, + util/grub-mkdevicemap.c, util/grub-probe.c and util/biosdisk.c. + * util/grub-emu.c: Replace grub/i386/pc/util/biosdisk.h with + grub/util/biosdisk.h. + * util/i386/pc/grub-setup.c: Replace grub/machine/util/biosdisk.h with + grub/util/biosdisk.h. + +2007-05-16 Robert Millan + + * util/grub.d/00_header.in: Set default gfxmode to `640x480'. + +2007-05-16 Robert Millan + + * util/i386/efi/grub-install.in: New. + * conf/i386-efi.rmk: Enable grub-mkdevicemap, grub-probe and the + newly added grub-install. + * util/biosdisk.c: Remove unnecessary grub/machine/biosdisk.h + include. + * util/getroot.c: Replace grub/i386/pc/util/biosdisk.h with + grub/util/biosdisk.h. + * util/grub-probe.c: Replace grub/machine/util/biosdisk.h with + grub/util/biosdisk.h. + +2007-05-16 Robert Millan + + * include/grub/i386/pc/util/biosdisk.h: Moved to ... + * include/grub/util/biosdisk.h: ... here. + * util/i386/pc/biosdisk.c: Moved to ... + * util/biosdisk.c: ... here. + * util/i386/pc/getroot.c: Moved to ... + * util/getroot.c: ... here. + * util/i386/pc/grub-mkdevicemap.c: Moved to ... + * util/grub-mkdevicemap.c: ... here. + * util/i386/pc/grub-probe.c: Moved to ... + * util/grub-probe.c: ... here. + +2007-05-15 Robert Millan + + * util/update-grub.in: Remove duplicated line in grub.cfg header + message. + +2007-05-13 Robert Millan + + * util/update-grub.in: Fix a few assumptions about the devices holding + /, /boot and /boot/grub being the same. + * util/grub.d/00_header.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + + * util/grub.d/10_linux.in: Implement Linux image sorting with arbitrary + patterns. Use that to define the `.old' suffix as older than `'. + + * util/grub.d/00_header.in: Set default gfxmode to `800x600x16'. + + * util/update-grub.in: Add a reference to ${sysconfdir}/default/grub in + the grub.cfg header message. + +2007-05-11 Robert Millan + + * util/update-grub.in: Create device.map if it doesn't already exist, + before attempting to run grub-probe. + Check for grub-probe and grub-mkdevicemap with the same code + grub-install is using. + Remove test mode. + +2007-05-09 Jeroen Dekkers + + * Makefile.in: Add the datarootdir autoconf variable. + +2007-05-09 Robert Millan + + * util/i386/pc/grub-probe.c (probe): When detecting partition map, + fail gracefully if dev->disk->partition == NULL. + +2007-05-07 Robert Millan + + * util/i386/pc/grub-probe.c: Add `grub-probe -t partmap' parameter to + determine partition map module. + * util/i386/pc/grub-install.in: Use this feature to decide which + partition module to load, instead of hardcoding pc and gpt. + +2007-05-07 Robert Millan + + * Makefile.in: Fix assumption that $(srcdir) has a trailing slash when + source directory differs from build directory. + +2007-05-05 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Fix syntax error in pkglibdir + initialisation. + +2007-05-05 Robert Millan + + * util/update-grub.in: Create ${grub_prefix} if it doesn't exist. + +2007-05-05 Robert Millan + + * util/grub.d/10_linux.in: Allow the administrator to insert Linux + command-line arguments via ${GRUB_CMDLINE_LINUX}. + +2007-05-05 Robert Millan + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/gpt.c. + (grub_probe_SOURCES): Likewise. + * util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): Detect + GPT and initialize dos_part and bsd_part accordingly. + * util/i386/pc/grub-setup.c (setup): Ditto for install_dos_part and + install_bsd_part. + (main): Activate gpt module for use during partition identification, + and deactivate it afterwards. + * util/i386/pc/grub-install.in: Add gpt module to core.img. + * util/i386/pc/grub-probe.c (main): Activate gpt module for use during + partition identification, and deactivate it afterwards. + +2007-05-05 Robert Millan + + * term/i386/pc/console.c (grub_console_fini): Call + grub_term_set_current() before grub_term_unregister(). + +2007-05-04 Robert Millan + + * DISTLIST: Add util/update-grub.in, util/grub.d/00_header.in, + util/grub.d/10_hurd.in, util/grub.d/10_linux.in and util/grub.d/README. + * Makefile.in: Build update-grub_SCRIPTS. Install update-grub_SCRIPTS + and update-grub_DATA. + * conf/common.rmk: Build and install update-grub components. + * conf/common.mk: Regenerate. + * util/update-grub.in: New. Core of update-grub. + * util/grub.d/00_header.in: New. Generates grub.cfg header. + * util/grub.d/10_hurd.in: New. Generates boot entries for the Hurd. + * util/grub.d/10_linux.in: New. Generates boot entries for Linux. + * util/grub.d/README: New. Document grub.d directory layout. + +2007-05-01 Robert Millan + + * util/grub-emu.c: Move initialization functions + grub_util_biosdisk_init() and grub_init_all() before + grub_util_biosdisk_get_grub_dev(), which relies on them. + +2007-04-19 Robert Millan + + * util/powerpc/ieee1275/grub-install.in: Initialize ${bindir}, since + it is used later. + +2007-04-18 Jerone Young + + * kernel/elf.c: Add missing parenthesis for conditional statement + stanza. + +2007-04-10 Jerone Young + + * util/i386/pc/getroot.c: Update so that if root device is /dev/root , + continue on and look for device node with real device name. + +2007-04-10 Jerone Young + + * configure.ac: Add argument for autoconf to use transformation + ability. + * Makefile.in: Add autoconf package transformation code. + * util/i386/pc/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-install.in: Likewise. + +2007-03-19 Yoshinori K. Okuji + + * fs/ext2.c (EXT2_GOOD_OLD_REVISION): New macro. + (EXT2_GOOD_OLD_INODE_SIZE): Likewise. + (EXT2_REVISION): Likewise. + (EXT2_INODE_SIZE): Likewise. + (struct grub_ext2_block_group): Added a missing member + "used_dirs". + (grub_ext2_read_inode): Divide by the inode size in a superblock + instead of 128 to obtain INODES_PER_BLOCK. + Use the macro EXT2_INODE_SIZE instead of directly using + SBLOCK->INODE_SIZE. + +2007-03-18 Yoshinori K. Okuji + + * fs/ext2.c (grub_ext2_read_inode): Use the inode size in a + superblock instead of the structure size to compute an + offset. This fixes the problem that GRUB could not read a + filesystem when inode size is different from 128-byte. + +2007-03-05 Marco Gerards + + * normal/main.c (read_config_file): When "menu" is not set, create + an initial context. + +2007-02-21 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (HEAP_SIZE): Removed. + (HEAP_LIMIT): New macro. + (grub_claim_heap): Claim memory up to `heaplimit'. + +2007-02-21 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (kernel_elf_LDFLAGS): Link at 64KB. + * kern/powerpc/ieee1275/init.c (_end): Add declaration. + (_start): Likewise. + (grub_arch_modules_addr): Return address after `_end'. + * util/powerpc/ieee1275/grub-mkimage.c: Include grub/misc.h. + (load_modules): Use new parameter as `p_paddr' and `p_vaddr'. + (add_segments): Calculate `_end' from phdr size and location. + (ALIGN_UP): Moved to ... + * include/grub/misc.h: here. + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MOD_ALIGN): + New macro. + (GRUB_IEEE1275_MODULE_BASE): Removed. + +2007-02-20 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_available_iterate): Correct + loop boundary. + +2007-02-20 Hollis Blanchard + + * include/grub/elfload.h (grub_elf32_load_hook_t): Return grub_err_t. + All users updated. + (grub_elf64_load_hook_t): Likewise. + * kern/elf.c: Call `grub_error_push' before `grub_error'. Improve + debug output. + +2007-02-20 Hollis Blanchard + + * kern/mm.c: Update copyright. + (grub_mm_debug): Correct syntax error. + (grub_mm_dump_free): New function. + (grub_debug_free): Call `grub_free'. + * include/grub/mm.h: Update copyright. + (grub_mm_dump_free): Add declaration. + +2007-02-12 Hollis Blanchard + + * include/grub/ieee1275/ieee1275.h: Update copyright. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + + * loader/powerpc/ieee1275/linux.c: Likewise. + * include/grub/elfload.h: Likewise. + * kern/elf.c: Likewise. + (grub_elf32_load): Pass `base' and `size' parameters. Update all + callers. + (grub_elf64_load): Likewise. + (grub_elf32_load_segment): Move to a nested function. + (grub_elf64_load_segment): Likewise. + +2007-02-12 Hollis Blanchard + + * include/grub/ieee1275/ieee1275.h (grub_available_iterate): New + prototype. + * kern/powerpc/ieee1275/init.c (grub_heap_start): Removed. + (grub_heap_len): Likewise. + (HEAP_SIZE): New macro. + (grub_claim_heap): New function. + (grub_machine_init): Don't claim heap directly. Call + `grub_claim_heap'. + * kern/powerpc/ieee1275/openfw.c: Include alloca.h. + (grub_available_iterate): New function. + +2007-02-03 Thomas Schwinge + + * aclocal.m4 (grub_CHECK_STACK_PROTECTOR): New definition. + * configure.ac: Use it for testing the HOST and TARGET compilers. + +2006-12-13 Thomas Schwinge + + * Makefile.in (enable_grub_emu): New variable. + * configure.ac (--enable-grub-emu): New option. + Do the checks for (n)curses only if `--enable-grub-emu' is requested. + * conf/i386-efi.rmk (sbin_UTILITIES): Add `grub-emu' only if requested. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk (bin_UTILITIES): Likewise. + +2006-12-12 Marco Gerards + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_MENU'. + + * kern/env.c (grub_env_unset): Don't free the member `value' when + the type is GRUB_ENV_VAR_DATA, in this case it's a user defined + pointer. + + * normal/main.c (current_menu): Removed. + (free_menu): Unset the `menu' environment variable. + (grub_normal_menu_addentry): Make use of the environment variable + `menu', instead of using the global `current_menu'. Allocate + memory for the sourcecode of this entry. + (read_config_file): New argument `nested', changed all callers. + Only in the case of a new context, initialize a new menu. Set the + `menu' environment variable. + (grub_normal_execute): Don't set and unset the environment + variable `menu' here anymore. Only free the menu when leaving the + context. + + * util/i386/pc/biosdisk.c (linux_find_partition): Fixed a memory + leak. + +2006-12-11 Marco Gerards + + * normal/menu_entry.c (run): Fix off by one bug so the last line + is executed. Move the loader check to outside the loop. + +2006-12-08 Hollis Blanchard + + * kern/powerpc/ieee1275/cmain.c (cmain): Mark r3 and r4 as `UNUSED'. + +2006-11-25 Yoshinori K. Okuji + + * util/i386/pc/grub-mkimage.c (generate_image): Fix the offset of + the number of sectors. Reported by Andrey Shuvikov + . + +2006-11-11 Jeroen Dekkers + + * kern/disk.c (grub_disk_read): When there is a read error, always + try to read only the necessary data. + + * conf/i386-pc.rmk (grub_probe_SOURCES): Add disk/lvm.c and + disk/raid.c. + * include/grub/disk.h [GRUB_UTIL] (grub_raid_init): New + prototype. + [GRUB_UTIL] (grub_raid_fini): Likewise. + [GRUB_UTIL] (grub_lvm_init): Likewise. + [GRUB_UTIL] (grub_lvm_fini): Likewise. + * util/i386/pc/grub-probe.c (probe): Check whether DEVICE_NAME is + RAID device and copy DEVICE_NAME to DRIVE_NAME in that case. + (main): Call grub_raid_init(), grub_lvm_init(), grub_lvm_fini() + and grub_raid_fini(). + +2006-11-09 Jeroen Dekkers + + * include/grub/types.h (__unused): Rename to UNUSED. + * kern/elf.c (grub_elf32_size): Use UNUSED instead of __unused. + (grub_elf64_size): Likewise. + +2006-11-03 Hollis Blanchard + + * kern/elf.c (grub_elf_file): Call grub_file_seek. Call + grub_error_push and grub_error_pop in the error-handling path. + (grub_elf32_load_segment): Only call grub_file_read with non-zero + length. + +2006-11-03 Hollis Blanchard + + * conf/i386-efi.rmk (grub_emu_SOURCES): Add kern/elf.c. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (kernel_elf_SOURCES): Likewise. + * conf/i386-efi.rmk (kernel_mod_HEADERS): Add elfload.h and cache.h. + * conf/i386-pc.rmk (kernel_mod_HEADERS): Likewise. + * conf/powerpc-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + * conf/sparc64-ieee1275.rmk (kernel_elf_HEADERS): Likewise. + * conf/common.rmk (pkgdata_MODULES): Add elf.mod. + (elf_mod_SOURCES): New variable. + (elf_mod_CFLAGS): Likewise. + (elf_mod_LDFLAGS): Likewise. + * include/grub/types.h (__unused): New macro. + * include/grub/elfload.h: New file. + * kern/elf.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Include elfload.h. + (ELF32_LOADMASK): New macro. + (ELF64_LOADMASK): Likewise. + (vmlinux): Removed. + (grub_linux_load32): New function. + (grub_linux_load64): Likewise. + (grub_rescue_cmd_linux): Call grub_linux_load32 or grub_linux_load64. + Use grub_elf_t instead of grub_file_t. + +2006-11-02 Hollis Blanchard + + * kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): Add + `catch_result' to struct set_color_args. + +2006-10-28 Yoshinori K. Okuji + + * normal/menu.c: Include grub/script.h. + * normal/menu_entry.c: Likewise. + * include/grub/normal.h: Do not include grub/script.h. + +2006-10-27 Hollis Blanchard + + * kern/disk.c (grub_disk_read): Correct debug printf formatting. + +2006-10-27 Hollis Blanchard + + * kern/disk.c (grub_disk_open): Print debug messages when opening a + disk. + (grub_disk_close): Print debug messages when closing a disk. + (grub_disk_read): Print debug messages when disk read fails. + * kern/fs.c (grub_fs_probe): Print debug messages when detecting + filesystem type. + * kern/partition.c: Include misc.h. + (grub_partition_iterate): Print debug messages when detecting + partition type. + +2006-10-27 Hollis Blanchard + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Return error if `status' + is negative. + * kern/ieee1275/ieee1275.c (IEEE1275_IHANDLE_INVALID): Change to 0. + +2006-10-26 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_encode_devname): + Reverse GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS test. + +2006-10-25 Jeroen Dekkers + + * disk/lvm.c (grub_lvm_scan_device): Malloc sizeof(*lv) bytes + instead of sizeof(lv). Patch by Michael Guntsche. + +2006-10-18 Jeroen Dekkers + + * disk/lvm.c: Rename VGS to VG_LIST. + (grub_lvm_iterate): Change VGS->LV to VG-LV. + (grub_lvm_open): Likewise. + Thanks to Michael Guntsche for finding this bug. + +2006-10-15 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Bumped to 1.95. + +2006-10-14 Robert Millan + + * util/i386/pc/getroot.c (grub_guess_root_device): Don't compare os_dev + with "/dev/.static/dev/md". + +2006-10-14 Yoshinori K. Okuji + + * util/i386/pc/grub-probe.c (probe): Print DEVICE_NAME instead of + DRIVE_NAME when grub_util_biosdisk_get_grub_dev fails. Open + DRIVE_NAME instead of DEVICE_NAME. Make sure that DEVICE_NAME and + DRIVE_NAME are always freed. + + * util/i386/pc/biosdisk.c (make_device_name): Add one into + DOS_PART, as a DOS partition is counted from one instead of zero + now. Reported by Robert Millan. + +2006-10-14 Robert Millan + + * util/i386/pc/getroot.c (grub_guess_root_device): Stop using + grub_util_biosdisk_get_grub_dev to convert system device to GRUB device. + * util/grub-emu.c (main): Use grub_util_biosdisk_get_grub_dev with the + string returned by grub_guess_root_device. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/grub-probefs.c: Likewise. + + * util/i386/pc/grub-probefs.c: Rename to ... + * util/i386/pc/grub-probe.c: ... this. + * DISTLIST: Remove grub-probefs, add grub-probe. + * conf/i386-efi.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * util/i386/pc/grub-install.in: Likewise. + + * util/i386/pc/grub-probe.c: Add --target=(fs|device|drive) option to + choose which information we want to print. + +2006-10-14 Yoshinori K. Okuji + + * DISTLIST: Added commands/echo.c, disk/lvm.c, disk/raid.c, + include/grub/bitmap.h, include/grub/lvm.h, include/grub/raid.h, + include/grub/i386/pc/vbeutil.h, include/grub/util/lvm.h, + include/grub/util/raid.h, util/lvm.c, util/raid.c, video/bitmap.c, + video/readers/tga.c and video/i386/pc/vbeutil.c. + +2006-10-14 Jeroen Dekkers + + Added support for RAID and LVM. + + * disk/lvm.c: New file. + * disk/raid.c: Likewise. + * include/grub/lvm.h: Likewise. + * include/grub/raid.h: Likewise. + * include/grub/util/lvm.h: Likewise. + * include/grub/util/raid.h: Likewise. + * util/lvm.c: Likewise. + * util/raid.c: Likewise. + + * include/grub/disk.h (grub_disk_dev_id): Add + GRUB_DISK_DEVICE_RAID_ID and GRUB_DISK_DEVICE_LVM_ID. + (grub_disk_get_size): New prototype. + * kern/disk.c (grub_disk_open): Check whether grub_partition_probe() + returns a partition. + (grub_disk_get_size): New function. + + * kern/i386/pc/init.c (make_install_device): Copy the prefix + verbatim if grub_install_dos_part is -2. + + * util/i386/pc/getroot.c (grub_guess_root_device): Support RAID + and LVM devices. + + * util/i386/pc/grub-setup.c (setup): New argument + MUST_EMBED. Force embedding of GRUB when the argument is + true. Close FILE before returning. + (main): Add support for RAID and LVM. + + * conf/common.rmk: Add RAID and LVM modules. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add util/raid.c and + util/lvm.c. + (grub_emu_SOURCES): Add disk/raid.c and disk/lvm.c. + + * kern/misc.c (grub_strstr): New function. + * include/grub/misc.h (grub_strstr): New prototype. + +2006-10-10 Tristan Gingold + + * include/grub/efi/api.h (GRUB_EFI_ERROR_CODE): Long constant. + +2006-10-05 Tristan Gingold + + * kern/misc.c (grub_strtoull): Guess the base only if not + specified. + +2006-10-01 Hollis Blanchard + + * kern/powerpc/ieee1275/cmain.c (cmain): Remove incomplete Old World + PowerMac support. + +2006-10-01 Hollis Blanchard + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Cast `size' to long. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_next_property): + Remove `flags' argument. All callers changed. + * kern/ieee1275/ieee1275.c (IEEE1275_PHANDLE_ROOT): Removed. + (IEEE1275_IHANDLE_INVALID): New variable. + (IEEE1275_CELL_INVALID): New variable. + (grub_ieee1275_finddevice, grub_ieee1275_get_property, + grub_ieee1275_get_property_length, grub_ieee1275_instance_to_package, + grub_ieee1275_package_to_path, grub_ieee1275_instance_to_path, + grub_ieee1275_peer, grub_ieee1275_child, grub_ieee1275_open, + grub_ieee1275_claim, grub_ieee1275_set_property): Error-check return + codes from Open Firmware. All callers updated. + (grub_ieee1275_next_property): Directly return Open Firmware return + code. + * kern/powerpc/ieee1275/cmain.c (grub_ieee1275_find_options): + Standardize error checking from `grub_ieee1275_get_property'. + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Rename + `devalias' to `aliases'. Correct comments. Consolidate error paths. + +2006-10-01 Hollis Blanchard + + * kern/ieee1275/ieee1275.c (grub_ieee1275_instance_to_path): Rename + `instance_to_package_args' to `instance_to_path_args'. + + * kern/powerpc/ieee1275/init.c (grub_machine_init): Use + `grub_ieee1275_chosen'. + + * term/ieee1275/ofconsole.c (grub_ofconsole_init): Call + `grub_ieee1275_interpret'. + +2006-09-25 Hollis Blanchard + + * util/powerpc/ieee1275/grub-mkimage.c: Include config.h. + +2006-09-25 Hollis Blanchard + + * include/grub/powerpc/libgcc.h (__floatdisf): New prototype. + (__cmpdi): Likewise. + + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Pass 0 as + `flags' to `grub_ieee1275_next_property'. Change `pathlen' to type + `grub_ssize_t'. + + * kern/powerpc/ieee1275/cmain.c: Include grub/misc.h. + + * loader/powerpc/ieee1275/linux.c (grub_linux_boot): Change `actual' + to type `grub_ssize_t'. + (grub_rescue_cmd_linux): Cast -1 to `grub_off_t'. + +2006-09-22 Marco Gerards + + * normal/script.c (grub_script_create_cmdmenu): Skip leading + newlines. + +2006-09-22 Marco Gerards + + * commands/echo.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/echo.c'. + + * conf/common.rmk (echo_mod_SOURCES): New variable. + (echo_mod_CFLAGS): Likewise. + (echo_mod_LDFLAGS): Likewise. + +2006-09-22 Marco Gerards + + * normal/main.c (get_line): Malloc memory instead of using + preallocated memory. Removed the arguments `cmdline' and + `max_len'. Updated all callers. + +2006-09-22 Marco Gerards + + * conf/i386-efi.rmk (grub_emu_DEPENDENCIES): New variable. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_DEPENDENCIES): Likewise. + (normal_mod_DEPENDENCIES): Likewise. + + * conf/sparc64-ieee1275.rmk (normal_mod_DEPENDENCIES): Likewise. + +2006-09-22 Johan Rydberg + + * genmk.rb: Add DEPENDENCIES variables to modules, utilities, and + programs. + * conf/i386-pc.rmk (grub_emu_DEPENDENCIES): Declare. + (normal_mod_DEPENDENCIES): Likewise. + * conf/i386-pc.mk: Regenerate. + * conf/i386-efi.mk: Likewise + * conf/common.mk: Likewise. + * conf/powerpc-ieee1275.mk: Likewise. + * conf/sparc64-ieee1275.mk: Likewise. + +2006-09-22 Robert Millan + + Sync with i386 version. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Remove grub-emu, add grub-mkimage. + * conf/powerpc-ieee1275.rmk (sbin_UTILITIES): Remove grub-mkimage, add grub-emu. + +2006-09-21 Robert Millan + + Import from GRUB Legacy (lib/device.c): + * util/i386/pc/grub-mkdevicemap.c (get_i2o_disk_name): New function. + (init_device_map) [__linux__]: Add support for I2O devices. + +2006-09-14 Marco Gerards + + * conf/i386-pc.rmk (COMMON_LDFLAGS): Use `-m32' instead of + `-melf_i386'. + +2006-09-14 Robert Millan + + * util/i386/pc/grub-install.in: Skip menu.lst when removing + /boot/grub/*.lst. + + * util/i386/pc/getroot.c: Don't recurse into dotdirs (e.g. ".static"). + + * util/i386/pc/grub-mkdevicemap.c: Make sure the floppy device exists + before adding it to device.map. + +2006-08-15 Johan Rydberg + + * genmk.rb: Let GCC generate dependencies the first time it + compiles a file; using the -MD option. + * conf/common.mk: Regenerate. + * conf/i386-pc.mk: Likewise. + * conf/i386-efi.mk: Likewise. + * conf/powerpc-ieee1275.mk: Likewise. + * conf/sparc64-ieee1275.mk: Likewise. + +2006-08-04 Yoshinori K. Okuji + + Move the prototypes of grub_setjmp and grub_longjmp to + cpu/setjmp.h, so that each architecture may specify different + attributes. + + * include/grub/i386/setjmp.h (grub_setjmp): New prototype. + (grub_longjmp): Likewise. + * include/grub/powerpc/setjmp.h (grub_setjmp): Likewise.. + (grub_longjmp): Likewise. + * include/grub/sparc64/setjmp.h (grub_setjmp): Likewise.. + (grub_longjmp): Likewise. + + * include/grub/setjmp.h [!GRUB_UTIL] (grub_setjmp): Removed. + [!GRUB_UTIL] (grub_longjmp): Removed. + +2006-08-01 Pelletier Vincent + + * kern/ieee1275/ieee1275.c (grub_ieee1275_set_color): IEEE1275 + "color!" method does not return any value. + +2006-07-29 Vesa Jaaskelainen + + * include/grub/bitmap.h: New file. + + * include/grub/i386/pc/vbeutil.h: Likewise. + + * video/bitmap.c: Likewise. + + * video/readers/tga.c: Likewise. + + * video/i386/pc/vbeutil.c: Likewise. + + * commands/videotest.c: Code cleanup and updated to reflect to new + video API. + + * term/gfxterm.c: Likewise. + + * video/video.c: Likewise. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added tga.mod and bitmap.mod. + (vbe_mod_SOURCES): Added video/i386/pc/vbeutil.c. + (bitmap_mod_SOURCES): New entry. + (bitmap_mod_CFLAGS): Likewise. + (bitmap_mod_LDFLAGS): Likewise. + (tga_mod_SOURCES): Likewise. + (tga_mod_CFLAGS): Likewise. + (tga_mod_LDFLAGS): Likewise. + + * include/grub/video.h (grub_video_blit_operators): New enum type. + (grub_video_render_target): Changed as forward declaration and moved + actual definition to be video driver specific. + (grub_video_adapter.blit_bitmap): Added blitting operator. + (grub_video_adapter.blit_render_target): Likewise. + (grub_video_blit_bitmap): Likewise. + (grub_video_blit_render_target): Likewise. + + * include/grub/i386/pc/vbe.h (grub_video_render_target): Added + driver specific render target definition. + (grub_video_vbe_map_rgba): Added driver internal helper. + (grub_video_vbe_unmap_color): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_vbe_get_video_ptr): Likewise. + + * include/grub/i386/pc/vbeblit.h + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8A8): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8A8): Likewise. + (grub_video_i386_vbeblit_R8G8B8A8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8): Likewise. + (grub_video_i386_vbeblit_index_index): Likewise. + (grub_video_i386_vbeblit_R8G8B8X8_R8G8B8X8): New blitter function. + (grub_video_i386_vbeblit_R8G8B8_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_index_R8G8B8X8): Likewise. + (grub_video_i386_vbeblit_blend): Added generic blitter for blend + operator. + (grub_video_i386_vbeblit_replace): Added generic blitter for replace + operator. + + * video/i386/pc/vbeblit.c: Updated to reflect changes on + include/grub/i386/pc/vbeblit.h. + + * include/grub/i386/pc/vbefill.h (grub_video_i386_vbefill_R8G8B8A8): + Updated to use grub_video_i386_vbeblit_info. + (grub_video_i386_vbefill_R8G8B8): Likewise. + (grub_video_i386_vbefill_index): Likewise. + (grub_video_i386_vbefill): Added generic filler. + + * video/i386/pc/vbefill.c: Updated to reflect changes on + include/grub/i386/pc/vbefill.h. + + * video/i386/pc/vbe.c (grub_video_vbe_get_video_ptr): Updated to use + grub_video_i386_vbeblit_info. + (grub_video_vbe_unmap_color): Likewise. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_scroll): Likewise. + (grub_video_vbe_draw_pixel): Removed function. + (grub_video_vbe_get_pixel): Likewise. + (grub_video_vbe_fill_rect): Moved all blitters to vbefill.c and + updated code to use it. + (common_blitter): Added common blitter for render target and bitmap. + (grub_video_vbe_blit_bitmap): Updated to use common_blitter. + (grub_video_vbe_blit_render_target): Likewise. + +2006-07-30 Johan Rydberg + + * kern/efi/efi.c (grub_efi_set_text_mode): Assume console already + is in text mode if there is no console control protocol instance + available. + +2006-07-29 Vesa Jaaskelainen + + * include/grub/video.h: Code cleanup. + + * include/grub/i386/pc/vbe.h: Likewise. + + * video/i386/pc/vbe.c: Likewise. + + * video/i386/pc/vbeblit.c: Likewise. + + * video/i386/pc/vbefill.c: Likewise. + + * video/video.c: Likewise. Also added more comments. + +2006-07-29 Vesa Jaaskelainen + + * disk/i386/pc/biosdisk.c (struct grub_biosdisk_drp): Moved to ... + (struct grub_biosdisk_dap): Likewise. + + * include/grub/i386/pc/biosdisk.h: ... to here. Also corrected + linkage settings for all functions. + +2006-07-12 Marco Gerards + + * configure.ac (--enable-mm-debug): Fix typo. + + * genkernsyms.sh.in: Use proper quoting for `CC'. + +2006-07-02 Jeroen Dekkers + + * conf/i386-pc.rmk (COMMON_ASFLAGS): Add "-m32". + (normal_mod_ASFLAGS): Remove "-m32". + +2006-06-14 Yoshinori K. Okuji + + * util/misc.c: Include config.h. + [!HAVE_MEMALIGN]: Do not include malloc.h. + (grub_memalign): Use posix_memalign, if present. Then, use + memalign, if present. Otherwise, emit an error. + + * util/grub-emu.c: Do not include malloc.h. + + * include/grub/util/misc.h: Include unistd.h. This is required for + FreeBSD, because off_t is defined in unistd.h. Reported by Harley + D. Eades III . + + * configure.ac (AC_GNU_SOURCE): Added. + (AC_CHECK_FUNCS): Check posix_memalign and memalign for the host + type. + +2006-06-09 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Make sure that + ADDR_MAX does not exceed GRUB_LINUX_INITRD_MAX_ADDRESS. + +2006-06-07 Jeroen Dekkers + + * include/grub/types.h (grub_host_addr_t): Rename to + grub_target_addr_t. + (grub_host_off_t): Rename to grub_target_off_t. + (grub_host_size_t): Rename to grub_target_size_t. + (grub_host_ssize_t): Rename to grub_target_ssize_t. + Refer to GRUB_TARGET_SIZEOF_VOID_P to define those variables. + + * include/grub/kernel.h (struct grub_module_header): Change type + of OFFSET to grub_target_off_t and type of SIZE to grub_target_size_t. + (grub_module_info): Likewise. + +2006-06-05 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): The conditional + of checking LINUX_MEM_SIZE was reverse. Reported by Jesus + Velazquez . + +2006-06-05 Yoshinori K. Okuji + + Count partitions from 1 instead of 0 in the string representation + of partitions. Still use 0-based internally. + + * partmap/sun.c (grub_sun_is_valid): A cosmetic change. + (sun_partition_map_iterate): Use grub_partition_t instead of + struct grub_partition *. Cast DESC->START_CYLINDER to + grub_uint64_t after converting the endian. + (sun_partition_map_probe): Subtract 1 for PARTNUM. + (sun_partition_map_get_name): Add 1 to P->INDEX. + + * partmap/pc.c (grub_partition_parse): Subtract 1 for + PCDATA->DOS_PART. + (pc_partition_map_get_name): Add 1 into PCDATA->DOS_PART. + + * partmap/gpt.c (gpt_partition_map_iterate): Initialize PARTNO to + zero instead of one. + (gpt_partition_map_probe): Subtract 1 for PARTNUM. + (gpt_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/apple.c (apple_partition_map_iterate): Change the type + of POS to unsigned. + (apple_partition_map_probe): Subtract 1 for PARTNUM. + (apple_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/amiga.c (amiga_partition_map_iterate): Change the type + of POS to unsigned. + (amiga_partition_map_iterate): Cast NEXT to grub_off_t to + calculate the offset of a partition. + (amiga_partition_map_probe): Subtract 1 for PARTNUM. + (amiga_partition_map_get_name): Add 1 into P->INDEX. + + * partmap/acorn.c (acorn_partition_map_find): Change the type of + SECTOR to grub_disk_addr_t. + (acorn_partition_map_iterate): Likewise. + (acorn_partition_map_probe): Subtract 1 for PARTNUM. + Change the type of SECTOR to grub_disk_addr_t. Declare P on the + top. + (acorn_partition_map_get_name): Add 1 into P->INDEX. + + * kern/i386/pc/init.c (make_install_device): Add 1 into + GRUB_INSTALL_DOS_PART. + + * fs/iso9660.c (grub_iso9660_mount): Fixed a reversed + conditional. + +2006-06-04 Yoshinori K. Okuji + + Clean up the code to support 64-bit addressing in disks and + files. This change is not enough for filesystems yet. + + * util/i386/pc/grub-setup.c (struct boot_blocklist): Change the + type of "start" to grub_uint64_t. + (setup): Change the types of KERNEL_SECTOR and FIRST_SECTOR to + grub_disk_addr_t * and grub_disk_addr_t. Fix the format string in + save_first_sector and save_blocklists. Use grub_le_to_cpu64 to + convert addresses. + + * util/i386/pc/biosdisk.c (open_device): Change the type of SECTOR + to grub_disk_addr_t. + + * partmap/gpt.c (gpt_partition_map_iterate): Fix the format + string. + + * partmap/pc.c (pc_partition_map_iterate): Likewise. + + * partmap/amiga.c (amiga_partition_map_iterate): Cast RDSK.MAGIC + to char *. + + * normal/script.c (grub_script_parse): Remove unused MEMFREE. + + * normal/parser.y (YYLTYPE_IS_TRIVIAL): New macro. + + * normal/lexer.c (grub_script_yyerror): Specify unused to LEX. + + * loader/i386/pc/multiboot.c (grub_multiboot_load_elf64): Cast -1 + to grub_off_t, to detect an error from grub_file_seek. + (grub_multiboot_load_elf32): Likewise. + + * kern/misc.c (grub_strtoul): Use grub_strtoull. Return the + maximum unsigned long value when an overflow is detected. + (grub_strtoull): New function. + (grub_divmod64): Likewise. + (grub_lltoa): use grub_divmod64. + + * kern/fs.c (struct grub_fs_block): Change the type of "offset" to + grub_disk_addr_t. + (grub_fs_blocklist_open): Increase P if P is not NULL to advance + the pointer to next character. Use grub_strtoull instead of + grub_strtoul. + (grub_fs_blocklist_read): Change the types of SECTOR, OFFSET and + SIZE to grub_disk_addr_t, grub_off_t and grub_size_t, + respectively. + + * kern/file.c (grub_file_read): Prevent an overflow of LEN, as the + return value is signed. + (grub_file_seek): Change the type of OLD to grub_off_t. Do not + test if OFFSET is less than zero, as OFFSET is unsigned now. + + * kern/disk.c (struct grub_disk_cache): Change the type of + "sector" to grub_disk_addr_t. + (grub_disk_cache_get_index): Change the type of SECTOR to + grub_disk_addr_t. Calculate the hash with SECTOR casted to + unsigned after shifting. + (grub_disk_cache_invalidate): Change the type of SECTOR to + grub_disk_addr_t. + (grub_disk_cache_unlock): Likewise. + (grub_disk_cache_store): Likewise. + (grub_disk_check_range): Change the types of SECTOR, OFFSET, SIZE, + START and LEN to grub_disk_addr_t *, grub_off_t *, grub_size_t, + grub_disk_addr_t and grub_uint64_t, respectively. + (grub_disk_read): Use an unsigned variable REAL_OFFSET for the + body, as the value of OFFSET is tweaked by + grub_disk_check_range. Change the types of START_SECTOR, LEN and + POS to grub_disk_addr_t, grub_size_t and grub_size_t, + respectively. + (grub_disk_write): Use an unsigned variable REAL_OFFSET for the + body, as the value of OFFSET is tweaked by + grub_disk_check_range. Change the types of LEN and N to + grub_size_t. + + * io/gzio.c (struct grub_gzio): Change the types of "data_offset" + and "saved_offset" to grub_off_t. + (test_header): Cast BUF to char *. + (get_byte): Cast GZIO->DATA_OFFSET to grub_off_t. Cast GZIO->INBUF + to char *. + (grub_gzio_read): Change the types of OFFSET and SIZE to + grub_off_t and grub_size_t, respectively. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_FORCE_LBA): + Removed. + (GRUB_BOOT_MACHINE_BOOT_DRIVE): Changed to 0x4c. + (GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Changed to 0x40. + (GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Changed to 0x42. + (GRUB_BOOT_MACHINE_DRIVE_CHECK): Changed to 0x4e. + (GRUB_BOOT_MACHINE_LIST_SIZE): Increased to 12. + + * include/grub/types.h (grub_off_t): Unconditionally set to + grub_uint64_t. + (grub_disk_addr_t): Changed to grub_uint64_t. + + * include/grub/partition.h (struct grub_partition): Change the + types of "start", "len" and "offset" to grub_disk_addr_t, + grub_uint64_t and grub_disk_addr_t, respectively. + (grub_partition_get_start): Return grub_disk_addr_t. + (grub_partition_get_len): Return grub_uint64_t. + + * include/grub/misc.h (grub_strtoull): New prototype. + (grub_divmod64): Likewise. + + * include/grub/fshelp.h (grub_fshelp_read_file): Change the types + of SECTOR, LEN and FILESIZE to grub_disk_addr_t, grub_size_t and + grub_off_t, respectively. + All callers and references changed. + + * include/grub/fs.h (struct grub_fs): Change the type of LEN to + grub_size_t in "read". + All callers and references changed. + + * include/grub/file.h (struct grub_file): Change the types of + "offset" and "size" to grub_off_t and grub_off_t, + respectively. Change the type of SECTOR to grub_disk_addr_t in + "read_hook". + (grub_file_read): Change the type of LEN to grub_size_t. + (grub_file_seek): Return grub_off_t. Change the type of OFFSET to + grub_off_t. + (grub_file_size): Return grub_off_t. + (grub_file_tell): Likewise. + All callers and references changed. + + * include/grub/disk.h (struct grub_disk_dev): Change the types of + SECTOR and SIZE to grub_disk_addr_t and grub_size_t in "read" and + "write". + (struct grub_disk): Change the type of "total_sectors" to + grub_uint64_t. Change the type of SECTOR to grub_disk_addr_t in + "read_hook". + (grub_disk_read): Change the types of SECTOR, OFFSET and SIZE to + grub_disk_addr_t, grub_off_t and grub_size_t, respectively. + (grub_disk_write): Likewise. + All callers and references changed. + + * fs/iso9660.c (grub_iso9660_susp_iterate): Cast parameters to + char * for grub_strncmp to silence gcc. + (grub_iso9660_mount): Likewise. + (grub_iso9660_mount): Likewise. + (grub_iso9660_read_symlink): Likewise. Also, remove the nonsense + return statement. + (grub_iso9660_iterate_dir): Likewise. + (grub_iso9660_label): Cast DATA->VOLDESC.VOLNAME to char *. + + * fs/hfs.c (grub_hfs_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * fs/hfsplus.c (grub_hfsplus_read_file): Likewise. + + * fs/jfs.c (grub_jfs_read_file): Likewise. + + * fs/minix.c (grub_jfs_read_file): Likewise. + + * fs/sfs.c (grub_jfs_read_file): Likewise. + + * fs/ufs.c (grub_jfs_read_file): Likewise. + + * fs/xfs.c (grub_jfs_read_file): Likewise. + + * fs/fat.c (grub_fat_read_data): Change the types of SECTOR, LEN + and SIZE to grub_disk_addr_t, grub_size_t and grub_size_t, + respectively. + + * fs/ext2.c (grub_ext2_read_block): When an error happens, set + BLKNR to -1 instead of returning GRUB_ERRNO. + (grub_ext2_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * fs/affs.c (grub_affs_read_file): Change the types of SECTOR and + LEN to grub_disk_addr_t and grub_size_t, respectively. + + * font/manager.c (grub_font_get_glyph): Cast BITMAP to char * for + grub_file_read. + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Fix the format + string. Do not cast SECTOR explicitly. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Change the type of + TOTAL_SECTORS to grub_uint64_t. Do not mask DRP->TOTAL_SECTORS. + (grub_biosdisk_rw): Change the types of SECTOR and SIZE to + grub_disk_addr_t and grub_size_t, respectively. If the sector is + over 2TB and LBA mode is not supported, raise an error. + (get_safe_sectors): New function. + (grub_biosdisk_read): Use get_safe_sectors. + (grub_biosdisk_write): Likewise. + + * disk/efi/efidisk.c (grub_efidisk_read): Fix the format string. + (grub_efidisk_write): Likewise. + + * disk/loopback.c (delete_loopback): Cosmetic changes. + (grub_cmd_loopback): Likewise. Also, test NEWDEV->FILENAME + correctly. + (grub_loopback_open): Likewise. + (grub_loopback_read): Likewise. Also, change the type of POS to + grub_off_t, and fix the usage of grub_memset. + + * commands/i386/pc/play.c: Include grub/machine/time.h. + + * commands/ls.c (grub_ls_list_files): Use "llu" instead of "d" to + print FILE->SIZE. + + * commands/configfile.c: Include grub/env.h. + + * commands/cmp.c (grub_cmd_cmp): Do not use ERR, but use + GRUB_ERRNO directly instead. Change the type of POS to + grub_off_t. Follow the coding standard. + + * commands/blocklist.c: Include grub/partition.h. + (grub_cmd_blocklist): Return an error if the underlying device is + not a disk. Take the starting sector of a partition into account, + if a partition is used. + + * boot/i386/pc/diskboot.S (bootloop): Adapted to the new offset of + a length field. + (lba_mode): Support 64-bit addresses. + (chs_mode): Likewise. + (copy_buffer): Adapted to the new offsets of a length field and a + segment field. + (blocklist_default_start): Allocate 64-bit space. + + * boot/i386/pc/boot.S (force_lba): Removed. + (boot_drive): Moved to under KERNEL_SECTOR. + (kernel_sector): Moved to under KERNEL_SEGMENT. Allocate 64-bit + space. + (real_start): Set %si earlier. Remove code for FORCE_LBA, since it + is useless. + (lba_mode): Refactored to support a 64-bit address. More size + optimization. + (setup_sectors): Likewise. + +2006-06-04 Yoshinori K. Okuji + + * DISTLIST: Added include/grub/i386/linux.h. Removed + include/grub/i386/pc/linux.h + + * configure.ac (AC_INIT): Bumped to 1.94. + + * config.guess: Updated from gnulib. + * config.sub: Likewise. + * install-sh: Likewise. + * mkinstalldirs: Likewise. + +2006-06-02 Yoshinori K. Okuji + + * conf/common.rmk (grub_modules_init.lst): Depended on + grub_emu_SOURCES, excluding grub_emu_init.c, instead of + MODSRCFILES. + + * genmk.rb (PModule::rule): Reverted the previous change. + +2006-06-02 Yoshinori K. Okuji + + * conf/common.rmk (grub_modules_init.lst): Depends on + $(MODSRCFILES). Grep only the files in $(MODSRCFILES). Make sure + that the target does not exist before producing. + (grub_modules_init.h): Remove the target before generating. + (grub_emu_init.c): Likewise. + + * genmk.rb (PModule::rule): Add source files into MODSRCFILES. + +2006-05-31 Jeroen Dekkers + + * configure.ac: Don't set host_m32 for x86_64. Also reset LIBS + for the target-specific tests. Make sure that we also have the + up-to-date target variables for those tests. + +2006-05-31 Yoshinori K. Okuji + + * genmk.rb (Image::rule): Prefix CFLAGS or ASFLAGS with TARGET_. + (PModule::rule): Likewise. + +2006-05-31 Yoshinori K. Okuji + + * genmk.rb (Image::rule): Set FLAG to CFLAGS or ASFLAGS instead of + TARGET_CFLAGS or TARGET_ASFLAGS. There is no reason why + target-specific flags should be prefixed. + (PModule::rule): Likewise. + +2006-05-30 Yoshinori K. Okuji + + * configure.ac (CMP): Check if cmp is available explicitly. + +2006-05-29 Yoshinori K. Okuji + + * util/powerpc/ieee1275/grub-install.in (host_cpu): Removed. + (target_cpu): New variable. + (pkglibdir): Use target_cpu instead of host_cpu. + + * util/i386/pc/grub-install.in (host_cpu): Removed. + (target_cpu): New variable. + (pkglibdir): Use target_cpu instead of host_cpu. + + * util/genmoddep.c: Removed. + + * kern/efi/mm.c (filter_memory_map): Use GRUB_CPU_SIZEOF_VOID_P + instead of GRUB_HOST_SIZEOF_VOID_P. + * kern/dl.c: Likewise. + + * include/grub/i386/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed to + ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + * include/grub/powerpc/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed + to ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + * include/grub/sparc64/types.h (GRUB_HOST_SIZEOF_VOID_P): Renamed + to ... + (GRUB_TARGET_SIZEOF_VOID_P): ... this. + (GRUB_HOST_SIZEOF_LONG): Renamed to ... + (GRUB_TARGET_SIZEOF_LONG): ... this. + (GRUB_HOST_WORDS_BIGENDIAN): Renamed to ... + (GRUB_TARGET_WORDS_BIGENDIAN): ... this. + + * include/grub/types.h [!GRUB_UTIL] (GRUB_CPU_SIZEOF_VOID_P): Use + GRUB_TARGET_SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P. + [!GRUB_UTIL] (GRUB_CPU_SIZEOF_LONG): Use GRUB_TARGET_SIZEOF_LONG + instead of GRUB_HOST_SIZEOF_LONG. + [!GRUB_UTIL]: Refer to GRUB_TARGET_WORDS_BIGENDIAN instead of + GRUB_HOST_WORDS_BIGENDIAN to define or undefine + GRUB_CPU_WORDS_BIGENDIAN. + Refer to SIZEOF_VOID_P instead of GRUB_HOST_SIZEOF_VOID_P to + define grub_host_addr_t, grub_host_off_t, grub_host_size_t and + grub_host_ssize_t. + + * conf/i386-efi.rmk (noinst_UTILITIES): Removed. + (genmoddep_SOURCES): Likewise. + * conf/i386-pc.rmk (noinst_UTILITIES): Likewise. + (genmoddep_SOURCES): Likewise. + * conf/conf/powerpc-ieee1275.rmk (noinst_UTILITIES): Likewise. + (genmoddep_SOURCES): Likewise. + * conf/conf/conf/sparc64-ieee1275.rmk (noinst_UTILITIES): + Likewise. + (genmoddep_SOURCES): Likewise. + + * genmoddep.awk: New file. + + * genmk.rb (Image::rule): Use TARGET_CC, TARGET_CPPFLAGS, + TARGET_CFLAGS, TARGET_ASFLAGS and TARGET_LDFLAGS instead of CC, + CPPFLAGS, CFLAGS, ASFLAGS and LDFLAGS, respectively. + (PModule::rule): Likewise. + (Program::rule): Likewise. + (Utility::rule): Use CC, CPPFLAGS, CFLAGS and LDFLAGS instead of + BUILD_CC, BUILD_CPPFLAGS, BUILD_CFLAGS and BUILD_LDFLAGS, + respectively. + + * configure.ac: Rewritten intensively to use host and target + instead of build and host, respectively. + + * Makefile.in (pkglibdir): Use target_cpu instead of host_cpu. + (host_cpu): Removed. + (target_cpu): New variable. + (CPPFLAGS): Added @CPPFLAGS@ and -DGRUB_LIBDIR=\"$(pkglibdir)\". + (BUILD_CC): Removed. + (BUILD_CFLAGS): Likewise. + (BUILD_CPPFLAGS): Likewise. + (TARGET_CC): New variable. + (TARGET_CFLAGS): Likewise. + (TARGET_CPPFLAGS): Likewise. + (TARGET_LDFLAGS): Likewise. + (AWK): Likewise. + (include): Use target_cpu instead of host_cpu. + (moddep.lst:): Use genmoddep.awk instead of genmoddep. + + * DISTLIST: Added genmoddep.awk. Removed util/genmoddep.c. + +2006-05-29 Vesa Jaaskelainen + + * include/grub/script.h (grub_script_cmdif): Renamed field 'bool' to + 'exec_to_evaluate'. Renamed field 'true' to 'exec_on_true'. Renamed + field 'false' to 'exec_on_false'. + (grub_script_create_cmdif): Renamed argument names to reflect above + changes. + + * normal/execute.c (grub_script_execute_cmdif): Likewise. + + * normal/script.c (grub_script_create_cmdif): Likewise. + +2006-05-28 Yoshinori K. Okuji + + * fs/hfsplus.c (grub_hfsplus_btree_recoffset): Moved to near the + top. + (grub_hfsplus_btree_recptr): Likewise. + (grub_hfsplus_find_block): Do not take RETRY any longer. Use + FILEBLOCK both to pass a block number and store next block + number. + (grub_hfsplus_read_block): Rewritten heavily to support an extent + overflow file correctly. Specify errors appropriately, because + fshelp expects that GRUB_ERRNO is set when fails. Reuse + grub_hfsplus_btree_recptr to get the pointer to a found key. + (grub_hfsplus_btree_search): Return 1 instead of 0 when no match + is found. + + * conf/i386-efi.rmk (pkgdata_MODULES): Added _linux.mod and + linux.mod. + (_linux_mod_SOURCES): New variable. + (_linux_mod_CFLAGS): Likewise. + (_linux_mod_LDFLAGS): Likewise. + (linux_mod_SOURCES): Likewise. + (linux_mod_CFLAGS): Likewise. + (linux_mod_LDFLAGS): Likewise. + + * DISTLIST: Added loader/i386/efi/linux.c, + loader/i386/efi/linux_normal.c and + include/grub/i386/efi/loader.h. + + * loader/i386/efi/linux.c: New file. + * loader/i386/efi/linux_normal.c: Likewise. + * include/grub/i386/efi/loader.h: Likewise. + +2006-05-27 Yoshinori K. Okuji + + * commands/blocklist.c: New file. + + * DISTLIST: Added commands/blocklist.c. + + * term/efi/console.c (grub_console_highlight_color): Use a lighter + color for the background, and a darker color for the foreground. + (grub_console_checkkey): Return READ_KEY. + (grub_console_cls): Set the background to + GRUB_EFI_BACKGROUND_BLACK temporarily to clean out the screen. + + * kern/efi/efi.c (grub_efi_exit_boot_services): New function. + + * include/grub/i386/linux.h (struct linux_kernel_params): Fixed + the size of "padding5", "hd0_drive_info" and "hd1_drive_info". + + * include/grub/efi/efi.h (grub_efi_exit_boot_services): New + prototype. + + * include/grub/efi/api.h (GRUB_EFI_TEXT_ATTR): Do not shift + BG. The spec is wrong again. + + * include/grub/normal.h [GRUB_UTIL] (grub_blocklist_init): New + prototype. + [GRUB_UTIL] (grub_blocklist_fini): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + commands/blocklist.c. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * conf/common.rmk (pkgdata_MODULES): Added blocklist.mod. + (blocklist_mod_SOURCES): New variable. + (blocklist_mod_CFLAGS): Likewise. + (blocklist_mod_LDFLAGS): Likewise. + +2006-05-20 Yoshinori K. Okuji + + * boot/i386/pc/boot.S (real_start): Set %si earlier to eliminate + duplication. + (lba_mode): Use %eax more intensively to reduce the code size. + +2006-05-20 Marco Gerards + + * normal/lexer.c (grub_script_yylex): Don't filter out newlines. + + * normal/parser.y (commandblock): Defined as . A subroutine + for `menuentry'. + (script): Accept leading newlines. + (newlines): New rule to describe 0 or more newlines. + (commands): Accept `command' with trailing newline. Fixed the + order in which arguments were passed to `grub_script_add_cmd'. + Accept commands separated by newlines. + (function): Changed to accept newlines. + (menuentry) Rewritten. + + * normal/script.c (grub_script_create_cmdmenu): Add new entries in + front of the list, instead of to the end. + +2006-05-19 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (bindir): New variable. + (grub_mkimage): Use BINDIR instead of SBINDIR. Reported by Lee + Shaver . + +2006-05-14 Yoshinori K. Okuji + + * kern/i386/pc/startup.S: Include grub/cpu/linux.h instead of + grub/machine/linux.h + * loader/i386/pc/linux.c: Likewise. + + * include/grub/i386/pc/linux.h: Moved to ... + * include/grub/i386/linux.h: ... here. + + * include/grub/i386/linux.h (struct linux_kernel_params): New + struct. + +2006-05-09 Vesa Jaaskelainen + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Corrected bounds + checking. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_blit_bitmap): Likewise. + (grub_video_vbe_blit_render_target): Likewise. + +2006-05-09 Yoshinori K. Okuji + + * configure.ac (--with-platform): Properly quote the square + brackets. + +2006-05-08 Marco Gerards + + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Renamed from + this... + (kernel_elf_HEADERS): ...to this. Updated all users. + (grubof_symlist.c): Renamed from this... + (kernel_elf_symlist.c): ...to this. Updated all users. + (pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'. + (grubof_SOURCES): Renamed from this... + (kernel_elf_SOURCES): ...to this. + (grubof_HEADERS): Renamed from this... + (kernel_elf_HEADERS): ...to this. + (grubof_CFLAGS): Renamed from this... + (kernel_elf_CFLAGS): ...to this. + (grubof_ASFLAGS): Renamed from this... + (kernel_elf_ASFLAGS): ...to this. + (grubof_LDFLAGS): Renamed from this... + (kernel_elf_LDFLAGS): ...to this. + + * conf/sparc64-ieee1275.rmk (grubof_HEADERS): Renamed from + this... + (kernel_elf_HEADERS): ...to this. Updated all users. + (grubof_symlist.c): Renamed from this... + (kernel_elf_symlist.c): ...to this. Updated all users. + (pkgdata_PROGRAMS): Changed `grubof' to `kernel.elf'. + (grubof_SOURCES): Renamed from this... + (kernel_elf_SOURCES): ...to this. + (grubof_HEADERS): Renamed from this... + (kernel_elf_HEADERS): ...to this. + (grubof_CFLAGS): Renamed from this... + (kernel_elf_CFLAGS): ...to this. + (grubof_ASFLAGS): Renamed from this... + (kernel_elf_ASFLAGS): ...to this. + (grubof_LDFLAGS): Renamed from this... + (kernel_elf_LDFLAGS): ...to this. + + * util/powerpc/ieee1275/grub-mkimage.c (add_segments): Use + `kernel.elf' instead of `grubof'. + +2006-05-08 Yoshinori K. Okuji + + Add --with-platform to configure. Use pkglibdir instead of + pkgdatadir. This is reported by Roger Leigh. + + * util/powerpc/ieee1275/grub-install.in (datadir): Removed. + (host_vendor): Likewise. + (host_os): Likewise. + (pkgdatadir): Likewise. + (platform): New variable. + (pkglibdir): Likewise. + Use PKGLIBDIR instead of PKGDATADIR. + + * util/i386/pc/grub-install.in (datadir): Removed. + (host_vendor): Likewise. + (host_os): Likewise. + (pkgdatadir): Likewise. + (platform): New variable. + (pkglibdir): Likewise. + Use PKGLIBDIR instead of PKGDATADIR. + + * util/powerpc/ieee1275/grub-mkimage.c (usage): Use GRUB_LIBDIR + instead of GRUB_DATADIR. + (main): Likewise. + * util/i386/pc/grub-mkimage.c (usage): Likewise. + (main): Likewise. + * util/i386/efi/grub-mkimage.c (usage): Likewise. + (main): Likewise. + + * configure.ac (--with-platform): New option. + Use PLATFORM instead of HOST_VENDOR to specify a platform. + + * Makefile.in: Include a makefile based on PLATFORM instead of + HOST_VENDOR. + (pkgdatadir): Not appended by the machine type. + (pkglibdir): Appended by the machine type. + (host_vendor): Removed. + (platform): New variable. + (BUILD_CPPFLAGS): Specify GRUB_LIBDIR instead of GRUB_DATADIR. + (install-local): Use PKGLIBDIR instead of PKGDATADIR. + (uninstall): Likewise. + +2006-05-07 Yoshinori K. Okuji + + Use the environment context in the menu. Remove the commands + "default" and "timeout", and use variables instead. + + * normal/menu.c: Include grub/env.h. + (print_entry): Cast TITLE to silence gcc. + (get_timeout): New function. + (set_timeout): Likewise. + (get_entry_number): Likewise. + (run_menu): Use a default entry, a fallback entry and a timeout + in the environment variables "default", "fallback" and + "timeout". Also, tweak the default entry if it is not within the + current menu entries. + (grub_menu_run): Use a fallback entry in the environment variable + "fallback". + + * normal/main.c (read_config_file): Do not initialize + NEWMENU->DEFAULT_ENTRY, NEWMENU->FALLBACK_ENTRY or + NEWMENU->TIMEOUT. + (grub_normal_execute): Use a data slot to store the menu. + + * include/grub/normal.h (struct grub_menu): Removed default_entry, + fallback_entry and timeout. + (struct grub_menu_list): Removed. + (grub_menu_list_t): Likewise. + (struct grub_context): Likewise. + (grub_context_t): Likewise. + (grub_context_get): Likewise. + (grub_context_get_current_menu): Likewise. + (grub_context_push_menu): Likewise. + (grub_context_pop_menu): Likewise. + (grub_default_init): Likewise. + (grub_default_fini): Likewise. + (grub_timeout_init): Likewise. + (grub_timeout_fini): Likewise. + + * conf/sparc64-ieee1275.rmk (pkgdata_MODULES): Removed default.mod + and timeout.mod. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Removed + commands/default.c, commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Removed commands/default.c, + commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/i386-efi.rmk (grub_emu_SOURCES): Removed + commands/default.c, commands/timeout.c and normal/context.c. + (normal_mod_SOURCES): Removed normal/context.c. + + * conf/common.rmk (pkgdata_MODULES): Removed default.mod and + timeout.mod. + (default_mod_SOURCES): Removed. + (default_mod_CFLAGS): Likewise. + (default_mod_LDFLAGS): Likewise. + (timeout_mod_SOURCES): Removed. + (timeout_mod_CFLAGS): Likewise. + (timeout_mod_LDFLAGS): Likewise. + + * DISTLIST: Removed commands/default.c, commands/timeout.c and + normal/context.c. + + * commands/default.c: Removed. + * commands/timeout.c: Likewise. + * normal/context.c: Likewise. + +2006-05-07 Vesa Jaaskelainen + + * kern/i386/pc/startup.S (grub_exit): Added missing .code32 tag. + +2006-05-02 Yoshinori K. Okuji + + * kern/env.c (struct grub_env_context): Removed "sorted". Renamed + "next" to "prev" for readability. + (struct grub_env_sorted_var): New struct. + (grub_env_context): Renamed to ... + (initial_context): ... this. + (grub_env_var_context): Renamed to ... + (current_context): ... this. + (grub_env_find): Look only at CURRENT_CONTEXT. + (grub_env_context_open): Rewritten to copy exported variables from + previous context. + (grub_env_context_close): Rewritten according to the new + scheme. Also, add an assertion to prevent the initial context from + removed. + (grub_env_insert): Removed the code for the sorted list. + (grub_env_remove): Likewise. + (grub_env_export): Simply mark the variable with + GRUB_ENV_VAR_GLOBAL. + (grub_env_set): A cosmetic change for naming consistency. + (grub_env_get): Likewise. + (grub_env_unset): Likewise. + (grub_env_iterate): Rewritten to sort variables within this + function. + (grub_register_variable_hook): Fixed for naming consistency. Call + grub_env_find again, only if NAME is not found at the first time. + (mangle_data_slot_name): New function. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + + * include/grub/env.h (grub_env_var_type): New enum. + (GRUB_ENV_VAR_LOCAL): New constant. + (GRUB_ENV_VAR_GLOBAL): Likewise. + (GRUB_ENV_VAR_DATA): Likewise. + (struct grub_env_var): Removed "sort_next" and "sort_prevp". Added + "type". + (grub_env_set): Replace VAR with NAME for consistency. + (grub_register_variable_hook): Likewise. + (grub_env_export): Specify the name of the argument. + (grub_env_set_data_slot): New prototype. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + +2006-04-30 Yoshinori K. Okuji + + Extend the loader so that GRUB can accept a loader which comes + back to GRUB when a loaded image exits. Also, this change adds + support for a chainloader on EFI. + + * term/efi/console.c: Include grub/misc.h. + (grub_console_checkkey): Display a scan code on the top for + debugging. This will be removed once the EFI port gets stable. + Correct the scan code mapping. + + * kern/efi/mm.c (sort_memory_map): Sort in a descending order to + allocate memory from larger regions, in order to reduce the number + of allocated regions. Otherwise, the MacOSX loader panics. + (filter_memory_map): Avoid less than 1MB for compatibility with + other loaders. + (add_memory_regions): Allocate from the tail of a region, if + possible, to avoid allocating a region near to 1MB, for the MacOSX + loader. + + * kern/efi/init.c (grub_efi_set_prefix): Specify + GRUB_EFI_IMAGE_HANDLE to grub_efi_get_loaded_image. + + * kern/efi/efi.c (grub_efi_get_loaded_image): Accept a new + argument IMAGE_HANDLE and specify it to get a loaded image. + (grub_arch_modules_addr): Specify GRUB_EFI_IMAGE_HANDLE to + grub_efi_get_loaded_image. + (grub_efi_get_filename): Divide the length by the size of + grub_efi_char16_t. + (grub_efi_get_device_path): New function. + (grub_efi_print_device_path): Print End Device Path nodes. Divide + the length by the size of grub_efi_char16_t for a file path device + path node. + + * kern/loader.c (grub_loader_noreturn): New variable. + (grub_loader_set): Accept a new argument NORETURN. Set + GRUB_LOADER_NORETURN to NORETURN. + All callers changed. + (grub_loader_boot): If GRUB_LOADER_NORETURN is false, do not call + grub_machine_fini. + + * include/grub/efi/efi.h (grub_efi_get_device_path): New + prototype. + (grub_efi_get_loaded_image): Take an argument to specify an image + handle. + + * include/grub/loader.h (grub_loader_set): Added one more argument + NORETURN. + + * disk/efi/efidisk.c (make_devices): Use grub_efi_get_device_path + instead of grub_efi_open_protocol. + (grub_efidisk_get_device_name): Likewise. + (grub_efidisk_close): Print a newline. + (grub_efidisk_get_device_handle): Fixed to use + GRUB_EFI_DEVICE_PATH_SUBTYPE instead of + GRUB_EFI_DEVICE_PATH_TYPE. + + * disk/efi/efidisk.c (device_path_guid): Moved to ... + * kern/efi/efi.c (device_path_guid): ... here. + + * conf/i386-efi.rmk (pkgdata_MODULES): Added _chain.mod and + chain.mod. + (kernel_mod_HEADERS): Added efi/disk.h. + (_chain_mod_SOURCES): New variable. + (_chain_mod_CFLAGS): Likewise. + (_chain_mod_LDFLAGS): Likewise. + (chain_mod_SOURCES): Likewise. + (chain_mod_CFLAGS): Likewise. + (chain_mod_LDFLAGS): Likewise. + + * DISTLIST: Added include/grub/efi/chainloader.h, + loader/efi/chainloader.c and loader/efi/chainloader_normal.c. + + * include/grub/efi/chainloader.h: New file. + * loader/efi/chainloader.c: Likewise. + * loader/efi/chainloader_normal.c: Likewise. + +2006-04-30 Marco Gerards + + * commands/configfile.c (grub_cmd_source): New function. + (GRUB_MOD_INIT): Register the commands `source' and `.'. + (GRUB_MOD_FINI): De-register the commands `source' and `.'. + +2006-04-30 Marco Gerards + + * normal/execute.c (grub_script_execute_cmd): Change the return + type to `grub_err_t'. Correctly return the error. + (grub_script_execute_cmdline): In case a command line is not a + command or a function, try to interpret it as an assignment. + +2006-04-30 Yoshinori K. Okuji + + * fs/hfsplus.c (grub_hfsplus_read_block): Fixed a memory leak. + (grub_hfsplus_iterate_dir): Reordered to skip unknown nodes. Also, + skip a node whose name is obviously invalid as UTF-16, + i.e. contains a NUL character. Stop the iteration when the last + directory entry is found. Instead of using the return value of + grub_hfsplus_btree_iterate_node, store the value in RET and use + it, because the iterator can be stopped by the last directory + entry. + +2006-04-30 Marco Gerards + + * include/grub/env.h (grub_env_export): New prototype. Reported + by Jan C. Kleinsorge . + +2006-04-30 Marco Gerards + + * fs/hfsplus.c (grub_hfsplus_iterate_dir): Correctly calculate the + size of the extents in a catalog file record. + +2006-04-29 Marco Gerards + + * commands/configfile.c (grub_cmd_configfile): Execute the + configfile within its own context. + + * include/grub/env.h (grub_env_context_open): New prototype. + (grub_env_context_close): Likewise. + + * kern/env.c (grub_env): Removed. + (grub_env_sorted): Likewise. + (grub_env_context): New variable. + (grub_env_var_context): Likewise. + (grub_env_find): Search both the active context and the global + context. + (grub_env_context_open): New function. + (grub_env_context_close): Likewise. + (grub_env_insert): Likewise. + (grub_env_remove): Likewise. + (grub_env_export): Likewise. + (grub_env_set): Changed to use helper functions to avoid code + duplication. + (grub_env_iterate): Rewritten so both the current context and the + global context are being used. + + * normal/command.c (export_command): New function. + (grub_command_init): Register the `export' function. + +2006-04-26 Yoshinori K. Okuji + + * util/i386/pc/grub-mkimage.c (compress_kernel): Cast arguments + explicitly to suppress gcc's warnings. + * fs/fat.c (grub_fat_find_dir): Likewise. + (grub_fat_label): Likewise. + * fs/xfs.c (grub_xfs_read_inode): Likewise. + (grub_xfs_mount): Likewise. + (grub_xfs_label): Likewise. + * fs/affs.c (grub_affs_mount): Likewise. + (grub_affs_label): Likewise. + (grub_affs_iterate_dir): Likewise. + * fs/sfs.c (grub_sfs_mount): Likewise. + (grub_sfs_iterate_dir): Likewise. + * fs/ufs.c (grub_ufs_lookup_symlink): Likewise. + * fs/hfs.c (grub_hfs_mount): Likewise. + (grub_hfs_cmp_catkeys): Likewise. + (grub_hfs_find_dir): Likewise. + (grub_hfs_dir): Likewise. + (grub_hfs_label): Likewise. + * fs/jfs.c (grub_jfs_mount): Likewise. + (grub_jfs_opendir): Likewise. + (grub_jfs_getent): Likewise. + (grub_jfs_lookup_symlink): Likewise. + (grub_jfs_label): Likewise. + * fs/hfsplus.c (grub_hfsplus_cmp_catkey): Likewise. + (grub_hfsplus_iterate_dir): Likewise. + (grub_hfsplus_btree_iterate_node): Made static. + + * util/grub-emu.c (prefix): New variable. + (grub_machine_set_prefix): New function. + (main): Do not set the environment variable "prefix" here. Only + set PREFIX, which is used later by grub_machine_set_prefix. + + * include/grub/video.h: Do not include grub/symbol.h. + (grub_video_register): Not exported. This symbol is not defined in + the kernel. + (grub_video_unregister): Likewise. + (grub_video_iterate): Likewise. + (grub_video_setup): Likewise. + (grub_video_restore): Likewise. + (grub_video_get_info): Likewise. + (grub_video_get_blit_format): Likewise. + (grub_video_set_palette): Likewise. + (grub_video_get_palette): Likewise. + (grub_video_set_viewport): Likewise. + (grub_video_get_viewport): Likewise. + (grub_video_map_color): Likewise. + (grub_video_map_rgb): Likewise. + (grub_video_map_rgba): Likewise. + (grub_video_fill_rect): Likewise. + (grub_video_blit_glyph): Likewise. + (grub_video_blit_bitmap): Likewise. + (grub_video_blit_render_target): Likewise. + (grub_video_scroll): Likewise. + (grub_video_swap_buffers): Likewise. + (grub_video_create_render_target): Likewise. + (grub_video_delete_render_target): Likewise. + (grub_video_set_active_render_target): Likewise. + + * include/grub/symbol.h [GRUB_SYMBOL_GENERATOR] (EXPORT_FUNC): + Undefined. + [GRUB_SYMBOL_GENERATOR] (EXPORT_VAR): Likewise. + + * conf/sparc64-ieee1275.rmk (grubof_symlist.c): Depended on + config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/powerpc-ieee1275.rmk (grubof_symlist.c): Depended on + config.h. Use gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/i386-pc.rmk (symlist.c): Depended on config.h. Use + gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * conf/i386-efi.rmk (symlist.c): Depended on config.h. Use + gensymlist.sh instead of $(srcdir)/gensymlist.sh. + (kernel_syms.lst): Depended on config.h. Use genkernsyms.sh + instead of $(srcdir)/genkernsyms.sh. + + * configure.ac (AC_CONFIG_FILES): Added gensymlist.sh and + genkernsyms.sh. + + * Makefile.in (DISTCLEANFILES): Added gensymlist.sh and + genkernsyms.sh. + (gensymlist.sh): New target. + (genkernsyms.sh): Likewise. + + * DISTLIST: Removed genkernsyms.sh and gensymlist.sh. Added + genkernsyms.sh.in and gensymlist.sh.in. + + * genkernsyms.sh: Removed. + * gensymlist.sh: Likewise. + + * genkernsyms.sh.in: New file. + * gensymlist.sh.in: Likewise. + +2006-04-25 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_machine_set_prefix): Do not + clobber "prefix", since we may have already set it manually. + +2006-04-25 Hollis Blanchard + + * kern/misc.c (abort): New alias for grub_abort. + +2006-04-25 Yoshinori K. Okuji + + A new machine-specific function "grub_machine_set_prefix" is + defined. This is called after loading modules, so that a prefix + initialization can use modules. Also, this change adds an + intensive debugging feature for the memory manager via the + configure option "--enable-mm-debug". + + * partmap/gpt.c (gpt_partition_map_iterate): Add one more into + PART.LEN. + + * kern/sparc64/ieee1275/init.c (abort): Removed. + (grub_stop): Likewise. + (grub_exit): New function. + (grub_set_prefix): Renamed to ... + (grub_machine_set_prefix): ... this. + (grub_machine_init): Do not call grub_set_prefix. + + * kern/powerpc/ieee1275/init.c (grub_set_prefix): Renamed to ... + (grub_machine_set_prefix): ... this. + (grub_machine_init): Do not call grub_set_prefix. + + * kern/i386/pc/init.c (grub_machine_set_prefix): New function. + (grub_machine_init): Do not set the prefix here. + + * kern/i386/efi/init.c (grub_machine_set_prefix): New function. + + * kern/efi/init.c: Include grub/mm.h. + (grub_efi_set_prefix): New function. + + * kern/efi/efi.c (grub_exit): Call grub_efi_fini. + (grub_efi_get_filename): New function. + (grub_print_device_path): Renamed to ... + (grub_efi_print_device_path): ... this. + + * kern/mm.c [MM_DEBUG] (grub_malloc): Undefined. + [MM_DEBUG] (grub_realloc): Likewise. + [MM_DEBUG] (grub_free): Likewise. + [MM_DEBUG] (grub_memalign): Likewise. + [MM_DEBUG] (grub_mm_debug): New variable. + [MM_DEBUG] (grub_debug_malloc): New function. + [MM_DEBUG] (grub_debug_free): New function. + [MM_DEBUG] (grub_debug_realloc): New function. + [MM_DEBUG] (grub_debug_memalign): New function. + + * kern/misc.c (grub_abort): Print a newline to distinguish + the message. + + * kern/main.c (grub_main): Call grub_machine_set_prefix and + grub_set_root_dev after loading modules. This is necessary when + setting a prefix depends on modules. + + * include/grub/efi/efi.h (grub_print_device_path): Renamed to ... + (grub_efi_print_device_path): ... this. + (grub_efi_get_filename): New prototype. + (grub_efi_set_prefix): Likewise. + + * include/grub/efi/disk.h: Include grub/efi/api.h, grub/symbol.h + and grub/disk.h. + (grub_efidisk_get_device_handle): New prototype. + (grub_efidisk_get_device_name): Likewise. + + * include/grub/mm.h: Include config.h. + (MM_DEBUG): Removed. + [MM_DEBUG && !GRUB_UTIL] (grub_mm_debug): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_malloc): New macro. + [MM_DEBUG && !GRUB_UTIL] (grub_realloc): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_memalign): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_free): Likewise. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_malloc): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_realloc): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_memalign): New prototype. + [MM_DEBUG && !GRUB_UTIL] (grub_debug_free): New prototype. + + * include/grub/kernel.h (grub_machine_set_prefix): New prototype. + + * disk/efi/efidisk.c: Include grub/partition.h. + (iterate_child_devices): New function. + (add_device): First, compare only last device path nodes, so that + devices are sorted by the types. + (grub_efidisk_get_device_handle): New function. + (grub_efidisk_get_device_name): Likewise. + + * configure.ac (--enable-mm-debug): New option to enable the + memory manager debugging feature. This makes the binary much + bigger, so is disabled by default. + +2006-04-23 Yoshinori K. Okuji + + Use grub_abort instead of grub_stop, and grub_exit must be + define in each architecture now. Also, this change adds support + for EFI disks. + + * util/i386/pc/grub-probefs.c: Include grub/term.h. + (grub_getkey): New function. + (grub_term_get_current): Likewise. + + * util/i386/pc/grub-setup.c: Include grub/term.h. + (grub_getkey): New function. + (grub_term_get_current): Likewise. + + * util/misc.c (grub_stop): Renamed to ... + (grub_exit): ... this. + + * kern/powerpc/ieee1275/init.c (abort): Renamed to ... + (grub_exit): ... this. + (grub_machine_init): Use grub_abort instead of abort. + (grub_stop): Removed. + + * kern/powerpc/ieee1275/cmain.c (cmain): Use grub_abort instead of + abort. + + * kern/i386/pc/startup.S (grub_exit): New function. + (cold_reboot): New label. + + * kern/efi/init.c: Include grub/efi/disk.h and grub/env.h. + (grub_efi_init): Call grub_efidisk_init. + (grub_efi_fini): Call grub_efidisk_fini. + + * kern/efi/efi.c: Include grub/mm.h. + (grub_efi_console_control_guid): Renamed to ... + (console_control_guid): ... this. + (grub_efi_loaded_image_guid): Renamed to ... + (loaded_image_guid): ... this. + (grub_efi_locate_handle): New function. + (grub_efi_open_protocol): Likewise. + (grub_efi_set_text_mode): Use CONSOLE_CONTROL_GUID instead of + GRUB_EFI_CONSOLE_CONTROL_GUID. + (grub_efi_exit): Removed. + (grub_stop): Likewise. + (grub_efi_get_loaded_image): Use grub_efi_open_protocol. + (grub_exit): New function. + (grub_print_device_path): Likewise. + + * kern/rescue.c (grub_rescue_cmd_exit): New function. + (grub_enter_rescue_mode): Register "exit". + + * kern/misc.c (grub_real_dprintf): A cosmetic change. + (grub_abort): New function. + + * kern/err.c (grub_fatal): Use grub_abort instead of grub_stop. + + * include/grub/sparc64/ieee1275/kernel.h (abort): Removed. + + * include/grub/powerpc/ieee1275/kernel.h (abort): Removed. + + * include/grub/efi/efi.h (grub_efi_exit): Removed. + (grub_print_device_path): New prototype. + (grub_efi_locate_handle): Likewise. + (grub_efi_open_protocol): Likewise. + + * include/grub/efi/disk.h (grub_efidisk_fini): New file. + * disk/efi/efidisk.c: Likewise. + + * DISTLIST: Added disk/efi/efidisk.c and include/grub/efi/disk.h. + + * include/grub/efi/console_control.h + (GRUB_EFI_CONSOLE_CONTROL_GUID): Use an array for the last 8 bytes. + + * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): Specify the + last 8 bytes as an array. + (GRUB_EFI_DISK_IO_GUID): New macro. + (GRUB_EFI_BLOCK_IO_GUID): Likewise. + (GRUB_EFI_DEVICE_PATH_GUID): Likewise. + (grub_efi_ipv6_address_t): Change the type to grub_uint16_t from + grub_uint8_t. + (struct grub_efi_guid): Use an array to specify the last 8 bytes. + (struct grub_efi_device_path): Rename the member "sub_type" to + "subtype". + (GRUB_EFI_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_DEVICE_PATH_LENGTH): Likewise. + (GRUB_EFI_END_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE): Likewise. + (GRUB_EFI_END_ENTIRE_DEVICE_PATH): Likewise. + (GRUB_EFI_NEXT_DEVICE_PATH): Likewise. + (GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_pci_device_path): New structure. + (grub_efi_pci_device_path_t): New type. + (GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_pccard_device_path): New structure. + (grub_efi_pccard_device_path_t): New type. + (GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_memory_mapped_device_path): New structure. + (grub_efi_memory_mapped_device_path_t): New type. + (GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_device_path): New structure. + (grub_efi_vendor_device_path_t): New type. + (GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_controller_device_path): New structure. + (grub_efi_controller_device_path_t): New type. + (GRUB_EFI_ACPI_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_acpi_device_path): New structure. + (grub_efi_acpi_device_path_t): New type. + (GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_expanded_acpi_device_path): New structure. + (grub_efi_expanded_acpi_device_path_t): New type. + (GRUB_EFI_EXPANDED_ACPI_HIDSTR): New macro. + (GRUB_EFI_EXPANDED_ACPI_UIDSTR): Likewise. + (GRUB_EFI_EXPANDED_ACPI_CIDSTR): Likewise. + (GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE): Likewise. + (GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_atapi_device_path): New structure. + (grub_efi_atapi_device_path_t): New type. + (GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_fibre_channel_device_path): New structure. + (grub_efi_fibre_channel_device_path_t): New type. + (GRUB_EFI_1394_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_1394_device_path): New structure. + (grub_efi_1394_device_path_t): New type. + (GRUB_EFI_USB_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_usb_device_path): New structure. + (grub_efi_usb_device_path_t): New type. + (GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_usb_class_device_path): New structure. + (grub_efi_usb_class_device_path_t): New type. + (GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_i2o_device_path): New structure. + (grub_efi_i2o_device_path_t): New type. + (GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_mac_address_device_path): New structure. + (grub_efi_mac_address_device_path_t): New type. + (GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_ipv4_device_path): New structure. + (grub_efi_ipv4_device_path_t): New type. + (GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_ipv6_device_path): New structure. + (grub_efi_ipv6_device_path_t): New type. + (GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_infiniband_device_path): New structure. + (grub_efi_infiniband_device_path_t): New type. + (GRUB_EFI_UART_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_uart_device_path): New structure. + (grub_efi_uart_device_path_t): New type. + (GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_messaging_device_path): New structure. + (grub_efi_vendor_messaging_device_path_t): New type. + (GRUB_EFI_MEDIA_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_hard_drive_device_path): New structure. + (grub_efi_hard_drive_device_path_t): New type. + (GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_cdrom_device_path): New structure. + (grub_efi_cdrom_device_path_t): New type. + (GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_vendor_media_device_path): New structure. + (grub_efi_vendor_media_device_path_t): New type. + (GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_file_path_device_path): New structure. + (grub_efi_file_path_device_path_t): New type. + (GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE): New macro. + (struct grub_efi_protocol_device_path): New structure. + (grub_efi_protocol_device_path_t): New type. + (GRUB_EFI_BIOS_DEVICE_PATH_TYPE): New macro. + (GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE): Likewise. + (struct grub_efi_bios_device_path): New structure. + (grub_efi_bios_device_path_t): New type. + (struct grub_efi_disk_io): New structure. + (grub_efi_disk_io_t): New type. + (struct grub_efi_block_io_media): New structure. + (grub_efi_block_io_media_t): New type. + (struct grub_efi_block_io): New structure. + (grub_efi_block_io_t): New type. + + * include/grub/misc.h (grub_stop): Removed. + (grub_exit): New prototype. + (grub_abort): Likewise. + + * include/grub/disk.h (enum grub_disk_dev_id): Added + GRUB_DISK_DEVICE_EFIDISK_ID. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Added + disk/efi/efidisk.c. + (kernel_syms.lst): Remove the target if an error occurs. + +2006-04-22 Yoshinori K. Okuji + + * kern/misc.c (grub_lltoa): Rewritten the decimal conversion part, + as it was simply too buggy. + +2006-04-21 Yoshinori K. Okuji + + * kern/misc.c (grub_lltoa): New function. + (grub_vsprintf): Added support for the long long suffix, + i.e. "ll". + +2006-04-20 Hollis Blanchard + + * Makefile.in (LDFLAGS): Add variable. + (LD): Remove variable. + * configure.ac: Add -m32 to LDFLAGS. + * genmk.rb (PModule#rule): Use $(CC) instead of $(LD). + * conf/powerpc-ieee1275.rmk (COMMON_LDFLAGS): Add variable. + (grubof_LDFLAGS): Use $(COMMON_LDFLAGS). + (_linux_mod_LDFLAGS, linux_mod_LDFLAGS, normal_mod_LDFLAGS, + suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS): New + variables. + * conf/sparc64-ieee1275.rmk (COMMON_LDFLAGS): Add -nostdlib. + * conf/i386-pc.rmk (COMMON_LDFLAGS): Add -nostdlib. + * conf/i386-efi.rmk (COMMON_LDFLAGS): Add -nostdlib. + +2006-04-20 Vesa Jaaskelainen + + * term/gfxterm.c (grub_gfxterm_getcharwidth): Fixed character + length for unknown glyph. + +2006-04-20 Yoshinori K. Okuji + + Add support for pre-loaded modules into the EFI port. + + * util/i386/efi/grub-mkimage.c (make_mods_section): Rewritten + completely. Accept one more argument DIR. The caller has changed. + + * kern/i386/efi/init.c (grub_arch_modules_addr): Removed. + + * kern/efi/efi.c: Include grub/efi/pe32.h and grub/kernel.h. + (grub_efi_loaded_image_guid): New variable. + (grub_efi_get_loaded_image): New function. + (grub_arch_modules_addr): Likewise. + + * include/grub/efi/efi.h (grub_efi_get_loaded_image): New + prototype. + + * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): New macro. + (struct grub_efi_loaded_image): New structure. + (grub_efi_loaded_image_t): New type. + +2006-04-20 Yoshinori K. Okuji + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Compare the file + size with GRUB_OS_AREA_SIZE as grub_size_t instead of + grub_ssize_t. Reported by Jeff Chua . + +2006-04-19 Roger Leigh + + * DISTLIST: Added `util/powerpc/ieee1275/grub-install.in'. + +2006-04-19 Yoshinori K. Okuji + + * DISTLIST: Added include/grub/efi/console.h, + include/grub/efi/time.h, include/grub/i386/efi/kernel.h, + kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c. + + * include/grub/efi/console.h: New file. + * include/grub/efi/time.h: Likewise. + * include/grub/i386/efi/kernel.h: Likewise. + * kern/efi/init.c: Likewise. + * kern/efi/mm.c: Likewise. + * term/efi/console.c: Likewise. + + * kern/i386/efi/init.c: Do not include grub/machine/time.h. + (grub_stop): Removed. + (grub_get_rtc): Likewise. + (grub_machine_init): Simply call grub_efi_init. + (grub_machine_fini): Call grub_efi_fini. + + * kern/efi/efi.c: Include grub/machine/time.h and grub/term.h. + (grub_efi_output_string): Removed. + (grub_efi_stall): New function. + (grub_stop): Likewise. + (grub_get_rtc): Likewise. + + * include/grub/efi/efi.h (grub_efi_output_string): Removed. + (grub_efi_stall): New prototype. + (grub_efi_allocate_pages): Likewise. + (grub_efi_free_pages): Likewise. + (grub_efi_get_memory_map): Likewise. + (grub_efi_mm_init): Likewise. + (grub_efi_mm_fini): Likewise. + (grub_efi_init): Likewise. + (grub_efi_fini): Likewise. + + * include/grub/i386/efi/time.h: Do not include + grub/symbol.h. Include grub/efi/time.h. + (GRUB_TICKS_PER_SECOND): Removed. + (grub_get_rtc): Likewise. + + * include/grub/efi/api.h (struct grub_efi_memory_descriptor): + Added padding. The EFI spec is buggy. + (GRUB_EFI_BLACK): New macro. + (GRUB_EFI_BLUE): Likewise. + (GRUB_EFI_GREEN): Likewise. + (GRUB_EFI_CYAN): Likewise. + (GRUB_EFI_RED): Likewise. + (GRUB_EFI_MAGENTA): Likewise. + (GRUB_EFI_BROWN): Likewise. + (GRUB_EFI_LIGHTGRAY): Likewise. + (GRUB_EFI_BRIGHT): Likewise. + (GRUB_EFI_DARKGRAY): Likewise. + (GRUB_EFI_LIGHTBLUE): Likewise. + (GRUB_EFI_LIGHTGREEN): Likewise. + (GRUB_EFI_LIGHTCYAN): Likewise. + (GRUB_EFI_LIGHTRED): Likewise. + (GRUB_EFI_LIGHTMAGENTA): Likewise. + (GRUB_EFI_YELLOW): Likewise. + (GRUB_EFI_WHITE): Likewise. + (GRUB_EFI_BACKGROUND_BLACK): Likewise. + (GRUB_EFI_BACKGROUND_BLUE): Likewise. + (GRUB_EFI_BACKGROUND_GREEN): Likewise. + (GRUB_EFI_BACKGROUND_CYAN): Likewise. + (GRUB_EFI_BACKGROUND_RED): Likewise. + (GRUB_EFI_BACKGROUND_MAGENTA): Likewise. + (GRUB_EFI_BACKGROUND_BROWN): Likewise. + (GRUB_EFI_BACKGROUND_LIGHTGRAY): Likewise. + (GRUB_EFI_TEXT_ATTR): Likewise. + + * conf/i386-efi.rmk (kernel_mod_SOURCES): Added kern/efi/efi.c, + kern/efi/init.c, kern/efi/mm.c, and term/efi/console.c. + (kernel_mod_HEADERS): Added efi/time.h. + +2006-04-18 Yoshinori K. Okuji + + * DISTLIST: Added conf/i386-efi.mk, conf/i386-efi.rmk, + include/grub/efi/api.h, include/grub/efi/console_control.h, + include/grub/efi/efi.h, include/grub/efi/pe32.h, + include/grub/i386/efi/time.h, kern/efi/efi.c, + kern/i386/efi/init.c, kern/i386/efi/startup.S, + and util/i386/efi/grub-mkimage.c. + + * Makefile.in (RMKFILES): Added i386-efi.rmk. + + * genmk.rb (PModule#rule): Do not export symbols if + #{prefix}_EXPORTS is set to "no". + + * conf/i386-efi.mk: New file. + * conf/i386-efi.rmk: Likewise. + * include/grub/efi/api.h: Likewise. + * include/grub/efi/console_control.h: Likewise. + * include/grub/efi/efi.h: Likewise. + * include/grub/efi/pe32.h: Likewise. + * include/grub/i386/efi/time.h: Likewise. + * kern/efi/efi.c: Likewise. + * kern/i386/efi/init.c: Likewise. + * kern/i386/efi/startup.S: Likewise. + * util/i386/efi/grub-mkimage.c: Likewise. + +2006-04-17 Marco Gerards + + * include/grub/script.h: Include and + "grub_script.tab.h". + (struct grub_lexer_param): New struct. + (struct grub_parser_param): Likewise. + (grub_script_create_arglist): Pass the state in an argument. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdblock): Likewise. + (grub_script_create_cmdif): Likewise. + (grub_script_create_cmdmenu): Likewise. + (grub_script_add_cmd): Likewise. + (grub_script_arg_add): Likewise. + (grub_script_lexer_ref): Likewise. + (grub_script_lexer_deref): Likewise. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (grub_script_mem_record): Likewise. + (grub_script_mem_record_stop): Likewise. + (grub_script_malloc): Likewise. + (grub_script_yylex): Likewise. + (grub_script_yyparse): Likewise. + (grub_script_yyerror): Likewise. + (grub_script_yylex): Likewise. + (grub_script_lexer_init): Return the state. + + * normal/lexer.c (grub_script_lexer_state): Removed variable. + (grub_script_lexer_done): Likewise. + (grub_script_lexer_getline): Likewise. + (grub_script_lexer_refs): Likewise. + (script): Likewise. + (newscript): Likewise. + (record): Likewise. + (recording): Likewise. + (recordpos): Likewise. + (recordlen): Likewise. + (grub_script_lexer_init): Return the state instead of setting + global variables. + (grub_script_lexer_ref): Use the newly added argument for state + instead of globals. + (grub_script_lexer_deref): Likewise. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (recordchar): Likewise. + (nextchar): Likewise. + (grub_script_yylex2): Likewise. + (grub_script_yylex): Likewise. + (grub_script_yyerror): Likewise. + + * normal/parser.y (func_mem): Removed variable. + (menu_entry): Likewise. + (err): Likewise. + (%lex-param): New parser option. + (%parse-param): Likewise. + (script): Always return the AST. + (argument): Pass the state around. + (arguments): Likewise. + (grubcmd): Likewise. + (commands): Likewise. + (function): Likewise. + (menuentry): Likewise. + (if_statement): Likewise. + (if): Likewise. + + * normal/script.c (grub_script_memused): Removed variable. + (grub_script_parsed): Likewise. + (grub_script_malloc): Added a state argument. Use that instead of + global variables. + (grub_script_mem_record): Likewise. + (grub_script_mem_record_stop): Likewise. + (grub_script_arg_add): Likewise. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdif): Likewise. + (grub_script_create_cmdmenu): Likewise. + (grub_script_add_cmd): Likewise. + (grub_script_parse): Setup the state before calling the parser. + +2006-04-16 Marco Gerards + + * normal/command.c (grub_command_init): Remove the title command. + + * normal/lexer.c (grub_script_yylex): Renamed from this... + (grub_script_yylex2): ... to this. + (grub_script_yylex): New function. Temporary + introduced to filter some tokens. + (grub_script_yyerror): Print a newline. + + * normal/main.c (read_config_file): Output information about the + lines that contain errors. Wait for a key after all lines have + been processed. Don't return an empty menu. + + * normal/parser.y (func_mem): Don't initialize. + (menu_entry): Likewise. + (err): New variable. + (script): Don't return anything when an error was encountered. + (ws, returns): Removed rules. + (argument): Disabled concatenated variable support. + (arguments): Remove explicit separators. + (grubcmd): Likewise. + (function): Likewise. + (menuentry): Likewise. + (if): Likewise. + (commands): Likewise. Add error handling. + + * normal/script.c (grub_script_create_cmdline): If + `grub_script_parsed' is 0, assume the parser encountered an error. + +2006-04-02 Yoshinori K. Okuji + + * configure.ac: Add support for EFI. Fix the typo + BUILD_LDDFLAGS. Restore the LDFLAGS after testing. + +2006-04-01 Vesa Jaaskelainen + + * util/unifont2pff.rb: Removed unnecessary byte ordering. Now + foreign multibyte characters should be shown correctly. + +2006-04-01 Vesa Jaaskelainen + + * normal/main.c (grub_normal_menu_addentry): Fixed menu size + calculation. + (read_config_file): Made it to close file before returning. + +2006-03-31 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/i386/pc/vbeblit.h, + include/grub/i386/pc/vbefill.h, video/i386/pc/vbeblit.c, + video/i386/pc/vbefill.c. + + * conf/i386-pc.rmk (vbe_mod_SOURCES): Added video/i386/pc/vbeblit.c, + video/i386/pc/vbefill.c. + + * include/grub/video.h (grub_video_blit_format): New enum. + (grub_video_mode_info): Added new member blit_format. + (grub_video_get_blit_format): New function prototype. + + * include/grub/i386/pc/vbe.h (grub_video_vbe_get_video_ptr): New + function prototype. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_unmap_color): Likewise. + + * include/grub/i386/pc/vbeblit.h: New file. + + * include/grub/i386/pc/vbefill.h: New file. + + * video/video.c (grub_video_get_blit_format): New function. + (grub_video_vbe_get_video_ptr): Re-declared as non-static. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_unmap_color): Likewise. + + * video/i386/pc/vbe.c (grub_video_vbe_fill_rect): Changed to use more + optimized fills. + (grub_video_vbe_blit_render_target): Changed to use more optimized + blits. + (grub_video_vbe_setup): Added detection for optimized settings. + (grub_video_vbe_create_render_target): Likewise. + + * video/i386/pc/vbeblit.c: New file. + + * video/i386/pc/vbefill.c: New file. + +2006-03-30 Vesa Jaaskelainen + + * font/manager.c (grub_font_get_glyph): Removed font fixup from + here... + + * util/unifont2pff.rb: ... and moved it to here. Improved argument + parsing to support both hex and dec ranges. If filename was missing + show usage information. + +2006-03-14 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/video.h, term/gfxterm.c, + video/video.c, commands/videotest.c. Removed term/i386/pc/vesafb.c. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added video.mod, + gfxterm.mod, videotest.mod. Removed vga.mod, vesafb.mod. + (video_mod_SOURCES): Added. + (video_mod_CFLAGS): Likewise. + (video_mod_LDFLAGS): Likewise. + (gfxterm_mod_SOURCES): Likewise. + (gfxterm_mod_CFLAGS): Likewise. + (gfxterm_mod_LDFLAGS): Likewise. + (videotest_mod_SOURCES): Likewise. + (videotest_mod_CFLAGS): Likewise. + (videotest_mod_LDFLAGS): Likewise. + (vesafb_mod_SOURCES): Removed. + (vesafb_mod_CFLAGS): Likewise. + (vesafb_mod_LDFLAGS): Likewise. + (vga_mod_SOURCES): Likewise. + (vga_mod_CFLAGS): Likewise. + (vga_mod_LDFLAGS): Likewise. + + * commands/videotest.c: New file. + + * font/manager.c (fill_with_default_glyph): Modified to use + grub_font_glyph. + (grub_font_get_glyph): Likewise. + (fontmanager): Renamed from this... + (font_manager): ... to this. + + * include/grub/font.h (grub_font_glyph): Added new structure. + (grub_font_get_glyph): Modified to use grub_font_glyph. + + * include/grub/misc.h (grub_abs): Added as inline function. + + * include/grub/video.h: New file. + + * include/grub/i386/pc/vbe.h (GRUB_VBE_STATUS_OK): New macro. + (GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL): Likewise. + (GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR): Likewise. + (grub_vbe_get_controller_info): Renamed from this... + (grub_vbe_bios_get_controller_info): ... to this. + (grub_vbe_get_mode_info): Renamed from this... + (grub_vbe_bios_get_mode_info): ... to this. + (grub_vbe_set_mode): Renamed from this... + (grub_vbe_bios_set_mode): ... to this. + (grub_vbe_get_mode): Renamed from this... + (grub_vbe_bios_get_mode): ... to this. + (grub_vbe_set_memory_window): Renamed from this... + (grub_vbe_bios_set_memory_window): ... to this. + (grub_vbe_get_memory_window): Renamed from this... + (grub_vbe_bios_get_memory_window): ... to this. + (grub_vbe_set_scanline_length): Renamed from this... + (grub_vbe_set_scanline_length): ... to this. + (grub_vbe_get_scanline_length): Renamed from this... + (grub_vbe_bios_get_scanline_length): ... to this. + (grub_vbe_set_display_start): Renamed from this... + (grub_vbe_bios_set_display_start): ... to this. + (grub_vbe_get_display_start): Renamed from this... + (grub_vbe_bios_get_display_start): ... to this. + (grub_vbe_set_palette_data): Renamed from this... + (grub_vbe_bios_set_palette_data): ... to this. + (grub_vbe_set_pixel_rgb): Removed. + (grub_vbe_set_pixel_index): Likewise. + + * kern/i386/pc/startup.S (grub_vbe_get_controller_info): Renamed + from this... + (grub_vbe_bios_get_controller_info): ... to this. + (grub_vbe_get_mode_info): Renamed from this... + (grub_vbe_bios_get_mode_info): ... to this. + (grub_vbe_set_mode): Renamed from this... + (grub_vbe_bios_set_mode): ... to this. + (grub_vbe_get_mode): Renamed from this... + (grub_vbe_bios_get_mode): ... to this. + (grub_vbe_set_memory_window): Renamed from this... + (grub_vbe_bios_set_memory_window): ... to this. + (grub_vbe_get_memory_window): Renamed from this... + (grub_vbe_bios_get_memory_window): ... to this. + (grub_vbe_set_scanline_length): Renamed from this... + (grub_vbe_set_scanline_length): ... to this. + (grub_vbe_get_scanline_length): Renamed from this... + (grub_vbe_bios_get_scanline_length): ... to this. + (grub_vbe_set_display_start): Renamed from this... + (grub_vbe_bios_set_display_start): ... to this. + (grub_vbe_get_display_start): Renamed from this... + (grub_vbe_bios_get_display_start): ... to this. + (grub_vbe_set_palette_data): Renamed from this... + (grub_vbe_bios_set_palette_data): ... to this. + (grub_vbe_bios_get_controller_info): Fixed problem with registers + getting corrupted after calling it. Added more pushes and pops. + (grub_vbe_bios_set_mode): Likewise. + (grub_vbe_bios_get_mode): Likewise. + (grub_vbe_bios_get_memory_window): Likewise. + (grub_vbe_bios_set_scanline_length): Likewise. + (grub_vbe_bios_get_scanline_length): Likewise. + (grub_vbe_bios_get_display_start): Likewise. + (grub_vbe_bios_set_palette_data): Likewise. + + * normal/cmdline.c (cl_set_pos): Refresh the screen. + (cl_insert): Likewise. + (cl_delete): Likewise. + + * term/gfxterm.c: New file. + + * term/i386/pc/vesafb.c: Removed file. + + * video/video.c: New file. + + * video/i386/pc/vbe.c (real2pm): Added new function. + (grub_video_vbe_draw_pixel): Likewise. + (grub_video_vbe_get_video_ptr): Likewise. + (grub_video_vbe_get_pixel): Likewise + (grub_video_vbe_init): Likewise. + (grub_video_vbe_fini): Likewise. + (grub_video_vbe_setup): Likewise. + (grub_video_vbe_get_info): Likewise. + (grub_video_vbe_set_palette): Likewise. + (grub_video_vbe_get_palette): Likewise. + (grub_video_vbe_set_viewport): Likewise. + (grub_video_vbe_get_viewport): Likewise. + (grub_video_vbe_map_color): Likewise. + (grub_video_vbe_map_rgb): Likewise. + (grub_video_vbe_map_rgba): Likewise. + (grub_video_vbe_unmap_color): Likewise. + (grub_video_vbe_fill_rect): Likewise. + (grub_video_vbe_blit_glyph): Likewise. + (grub_video_vbe_blit_bitmap): Likewise. + (grub_video_vbe_blit_render_target): Likewise. + (grub_video_vbe_scroll): Likewise. + (grub_video_vbe_swap_buffers): Likewise. + (grub_video_vbe_create_render_target): Likewise. + (grub_video_vbe_delete_render_target): Likewise. + (grub_video_vbe_set_active_render_target): Likewise. + (grub_vbe_set_pixel_rgb): Remove function. + (grub_vbe_set_pixel_index): Likewise. + (index_color_mode): Remove static variable. + (active_mode): Likewise. + (framebuffer): Likewise. + (bytes_per_scan_line): Likewise. + (grub_video_vbe_adapter): Added new static variable. + (framebuffer): Likewise. + (render_target): Likewise. + (initial_mode): Likewise. + (mode_in_use): Likewise. + (mode_list): Likewise. + +2006-03-10 Marco Gerards + + * configure.ac (AC_INIT): Bumped to 1.93. + + * DISTLIST: Added `include/grub/hfs.h'. + +2006-02-01 Yoshinori K. Okuji + + * boot/i386/pc/boot.S (general_error): Before looping, try INT + 18H, which might help the BIOS falling back to next boot media. + +2006-01-25 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in: Escape a backslash. Reported by + Poe Chen . + +2006-01-17 Marco Gerards + + * include/grub/normal.h: Include . + (grub_command_list): Removed struct. + (grub_command_list_t): Removed type. + (grub_menu_entry): Remove members `num' and `command_list'. Add + members `commands' and `sourcecode'. + * include/grub/script.h: Add inclusion guards. + (grub_script_cmd_menuentry): New struct. + (grub_script_execute_menuentry): New prototype. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + * normal/execute.c (grub_script_execute_menuentry): New function. + * normal/lexer.c (record, recording, recordpos, recordlen): New + variables. + (grub_script_lexer_record_start): New function. + (grub_script_lexer_record_stop): Likewise. + (recordchar): Likewise. + (nextchar): Likewise. + (grub_script_yylex): Use `nextchar' to fetch new characters. Use + 2048 as the buffer size. Add the tokens `menuentry' and `@'. + * normal/main.c: Include and + (current_menu): New variable. + (free_menu): Mainly rewritten. + (grub_normal_menu_addentry): New function. + (read_config_file): Rewritten. + * normal/menu.c (run_menu_entry): Mainly rewritten. + * normal/menu_entry.c (make_screen): Rewritten the code to insert + the menu entry. + (run): Mainly rewritten. + * normal/parser.y (menu_entry): New variable. + (GRUB_PARSER_TOKEN_MENUENTRY): New token. + (menuentry): New rule. + (command): Add `menuentry'. + (if_statement): Allow additional returns before `fi'. + * normal/script.c (grub_script_create_cmdmenu): New function. + +2006-01-03 Marco Gerards + + * INSTALL: GNU Bison is required. + * configure.ac: Rewritten the test to detect Bison. + * Makefile.in (YACC): New variable. Reported by Xun Sun + . + +2006-01-03 Marco Gerards + + * fs/hfsplus.c (grub_hfsplus_read_block): Convert the offset of + the HFS+ filesystem to filesystem blocks. + (grub_hfsplus_iterate_dir): Cast the `fileinfo' assignment so a + GCC warning is silenced. + +2006-01-03 Marco Gerards + + * partmap/apple.c (apple_partition_map_iterate): Convert the data + read from disk from big endian to host byte order. + +2006-01-03 Hollis Blanchard + + * fs/hfs.c: Include . Added reference to the official + documentation. + (GRUB_HFS_EMBED_HFSPLUS_SIG): New macro. + (grub_hfs_mount): Grammar fix in error. Make sure this is not an + embedded HFS+ filesystem. + (GRUB_HFS_MAGIC, grub_hfs_extent, grub_hfs_datarecord_t) + (grub_hfs_sblock): Move from here... + * include/grub/hfs.h: To here... New file. + * fs/hfsplus.c: Include . Added reference to the official + documentation. + (GRUB_HFSPLUS_MAGIC, GRUB_HFSPLUSX_MAGIC, GRUB_HFSPLUS_SBLOCK): + New macros. + (grub_hfsplus_volheader): Change type of member `magic' to + `grub_uint16_t'. + (grub_hfsplus_data): Add new member `embedded_offset'. + (grub_hfsplus_read_block): Add the HFS+ wrapper offset to the + returned block. + (grub_hfsplus_mount): Read the HFS+ wrapper if it exists. + Calculate the offset. + +2005-12-25 Yoshinori K. Okuji + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRP_ADDR): + Removed. + (GRUB_BOOT_MACHINE_DRP_SIZE): Likewise. + +2005-12-25 Yoshinori K. Okuji + + * kern/env.c (grub_env_set): Check if ENV->VALUE instead of + ENV->NAME is NULL after allocating ENV->VALUE. + +2005-12-25 Marco Gerards + + * kern/env.c (grub_env_set): Rewritten the error handling code. + +2005-12-25 Yoshinori K. Okuji + + * geninit.sh: Made more robust, and more portable. + +2005-12-25 Marco Gerards + + Add support for Apple HFS+ filesystems. + + * fs/hfsplus.c: New file. + + * DISTLIST: Added `fs/hfsplus.c'. + + * conf/common.rmk (pkgdata_MODULES): Add `hfsplus.mod'. + (hfsplus_mod_SOURCES): New variable. + (hfsplus_mod_CFLAGS): Likewise. + (hfsplus_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/hfsplus.c'. + (grub_setup_SOURCES): Likewise. + (grub_mkdevicemap_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + + * fs/fshelp.c (grub_fshelp_log2blksize): New function. + + * include/grub/fshelp.h (grub_fshelp_log2blksize): new prototype. + +2005-12-25 Yoshinori K. Okuji + + * DISTLIST: Added geninitheader.sh, geninit.sh, commands/test.c, + commands/i386/pc/play.c, conf/common.mk, conf/common.rmk, + include/grub/parser.h, include/grub/script.h, kern/parser.c, + kern/sparc64/cache.S, normal/execute.c, normal/function.c, + normal/lexer.c, normal/parser.y, normal/script.c, and + partmap/gpt.c. + Removed kern/sparc64/cache.c. + + * conf/common.rmk (DISTCLEANFILES): Added grub_script.tab.c, + grub_script.tab.h, grub_modules_init.lst, grub_modules_init.h, + grub_emu_init.c. + + * configure.ac (AC_INIT): Bumped to 1.92. + +2005-12-24 Vesa Jaaskelainen + + * kern/err.c (grub_error_push): Added new function to support error + stacks. + (grub_error_pop): Likewise. + (grub_error_stack_items): New local variable to support error stacks. + (grub_error_stack_pos): Likewise. + (grub_error_stack_assert): Likewise. + (GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error + stack depth. + (grub_print_error): Added support to print errors from error stack. + + * include/grub/err.h (grub_error_push): Added function prototype. + (grub_error_pop): Likewise. + +2005-12-09 Hollis Blanchard + + * configure.ac: Accept `powerpc64' as host_cpu. + (amd64): Rename to `biarch32'. + + * kern/powerpc/cache.S (grub_arch_sync_caches): Handle + non-cacheline-aligned addresses. + + * kern/dl.c (grub_dl_load_core): Add grub_dprintf messages. + (grub_dl_flush_cache): Likewise. Only call `grub_arch_sync_caches' + if `size' is non-zero. + +2005-12-03 Marco Gerards + + * conf/common.rmk (grub_modules_init.lst): Use `-printf "%P\n"' + and `cd' to make sure the filename is not prefixed with a + directory name. + (pkgdata_MODULES): Add `gpt.mod'. + (gpt_mod_SOURCES): New variable. + (gpt_mod_CFLAGS): Likewise. + (gpt_mod_LDFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/gpt.c'. + + * include/grub/pc_partition.h (GRUB_PC_PARTITION_TYPE_GPT_DISK): + New macro. + + * partmap/gpt.c: New file. + + * partmap/pc.c (pc_partition_map_iterate): Don't continue when a + GPT partition map is detected. + +2005-12-03 Vincent Pelletier + + * commands/i386/pc/play.c: New file. + * conf/i386-pc.rmk (pkgdata_MODULES): Added play.mod. + (play_mod_SOURCES, play_mod_CFLAGS, play_mod_LDFLAGS): New + macros. + +2005-11-27 Marco Gerards + + * include/grub/dl.h (GRUB_MOD_INIT): Use `__attribute__ + ((unused))' to silence gcc warning. + +2005-11-26 Hollis Blanchard + + * configure.ac: Correct `AC_PROG_YACC' test. + +2005-11-22 Hollis Blanchard + + * util/powerpc/ieee1275/grub-install.in: Run the mount point + check before installing files. + +2005-11-22 Mike Small + + * util/powerpc/ieee1275/grub-install.in (grubdir): Fixed partition + number regex so multidigit numbers are recognized correctly. + +2005-11-22 Mike Small + + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Add a + debugging message before attempting to claim memory. + (grub_rescue_cmd_initrd): Add a claim debugging message and try + multiple addresses in case of failure. + +2005-11-22 Hollis Blanchard + + * term/tparm.c (get_space): Remove empty `if' statement. + + * fs/ufs.c (grub_ufs_find_file): Remove `grub_le_to_cpu32'. + + * kern/parser.c (check_varstate): Rename `state' to 's'. + +2005-11-22 Hollis Blanchard + + * partmap/acorn.c: Change `unsigned' to `unsigned int'. Move all + variable definitions to the beginning of each function. Sort stack + variables by size. + (find): Rename to `acorn_partition_map_find'. Cast `grub_disk_read' + `buf' argument to `char *'. + +2005-11-22 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk: Include conf/common.mk. + (pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod, + minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod, + hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod, + help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod, + sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod, + configfile.mod, search.mod, gzio.mod and test.mod. + (symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst) + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c) + (fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS) + (fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS) + (ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS) + (hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES) + (jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES) + (iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES) + (hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES) + (terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES) + (ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS) + (help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS) + (font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS) + (terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS) + (amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Removed. + + * conf/common.mk (grub_modules_init.lst): Use `find' instead of + `grep --include'. + (pkgdata_MODULES): Add test.mod. + +2005-11-18 Timothy Baldwin + + * genmk.rb: Fixed list rules moved to Makefile.in. Recognise + appending to variables with "+=". + (PModule): Use full pathname to generate *.lst filenames. + + * Makefile.in: Fixed list rules moved from genmk.rb. + (.DELETE_ON_ERROR): New special target. + (RMKFILES): Add common.rmk and sparc64-ieee1275.rmk. + + * conf/i386-pc.rmk: Include conf/common.mk. + (pkgdata_MODULES): Removed fshelp.mod, fat.mod, ext2.mod, ufs.mod, + minix.mod, hfs.mod, jfs.mod, xfs.mod, affs.mod, sfs.mod, + hello.mod, boot.mod, terminal.mod, ls.mod, cmp.mod, cat.mod, + help.mod, font.mod, terminfo.mod, amiga.mod, apple.mod, pc.mod, + sun.mod, acorn.mod, loopback.mod, default.mod, timeout.mod, + configfile.mod, search.mod, gzio.mod and test.mod. + (symlist.c, grub_script.tab.c, grub_script.tab.h, kernel_syms.lst) + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c) + (fshelp_mod_SOURCES, fshelp_mod_CFLAGS, fshelp_mod_LDFLAGS) + (fat_mod_SOURCES, fat_mod_CFLAGS, fat_mod_LDFLAGS) + (ext2_mod_SOURCES, ext2_mod_CFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_SOURCES, ufs_mod_CFLAGS, ufs_mod_LDFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, minix_mod_LDFLAGS) + (hfs_mod_SOURCES, hfs_mod_CFLAGS, hfs_mod_LDFLAGS, jfs_mod_SOURCES) + (jfs_mod_CFLAGS, jfs_mod_LDFLAGS, iso9660_mod_SOURCES) + (iso9660_mod_CFLAGS, iso9660_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, hello_mod_SOURCES) + (hello_mod_CFLAGS, hello_mod_LDFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, boot_mod_LDFLAGS, terminal_mod_SOURCES) + (terminal_mod_CFLAGS, terminal_mod_LDFLAGS, ls_mod_SOURCES) + (ls_mod_CFLAGS, ls_mod_LDFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cmp_mod_LDFLAGS, cat_mod_SOURCES, cat_mod_CFLAGS, cat_mod_LDFLAGS) + (help_mod_SOURCES, help_mod_CFLAGS, help_mod_LDFLAGS) + (font_mod_SOURCES, font_mod_CFLAGS, font_mod_LDFLAGS) + (terminfo_mod_SOURCES, terminfo_mod_CFLAGS, terminfo_mod_LDFLAGS) + (amiga_mod_SOURCES, amiga_mod_CFLAGS, amiga_mod_LDFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, apple_mod_LDFLAG): Move from + here... + * conf/common.rmk: ... to here. New file. + + * conf/common.mk: New file. + +2005-11-18 Yoshinori K. Okuji + + * conf/powerpc-ieee1275.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * conf/sparc64-ieee1275.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * conf/i386-pc.rmk (grub_script.tab.h): Unified to ... + (grub_script.tab.c): ... here. + + * normal/command.c (grub_command_find): Fixed a memory leak of + MODULE_NAME. Reported by Mike Small . + +2005-11-13 Timothy Baldwin + + * include/grub/symbol.h: (FUNCTION): Use double quotes instead of + "@" which marks the start of a comment on ARM. + (VARIABLE): Likewise. + +2005-11-13 Timothy Baldwin + + Add support for Linux/ADFS partition tables. + + * partmap/acorn.c: New file. + + * include/grub/acorn_filecore.h: Likewise. + + * DISTLIST: Added `partmap/acorn.c' and + `include/grub/acorn_filecore.h'. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `partmap/acorn.c'. + (pkgdata_MODULES): Add `acorn.mod'. + (acorn_mod_SOURCES): New variable. + (acorn_mod_CFLAGS): Likewise. + (acorn_mod_LDFLAGS): Likewise. + + * include/types.h (grub_disk_addr_t): New typedef. + +2005-11-13 Marco Gerards + + * geninit.sh: New file. + + * geninitheader.sh: Likewise. + + * commands/boot.c (grub_boot_init, grub_boot_fini): Removed. + * commands/cat.c (grub_cat_init, grub_cat_fini): Likewise. + * commands/cmp.c (grub_cmp_init, grub_cmp_fini): Likewise. + * commands/configfile.c (grub_configfile_init) + (grub_configfile_fini): Likewise. + * commands/default.c (grub_default_init, grub_default_fini): + Likewise. + * commands/help.c (grub_help_init, grub_help_fini): Likewise. + * commands/ls.c (grub_ls_init, grub_ls_fini): Likewise. + * commands/search.c (grub_search_init, grub_search_fini): Likewise. + * commands/terminal.c (grub_terminal_init, grub_terminal_fini): + Likewise. + * commands/test.c (grub_test_init, grub_test_fini): Likewise. + * commands/timeout.c (grub_timeout_init, grub_timeout_fini): + Likewise. + * commands/i386/pc/halt.c (grub_halt_init, grub_halt_fini): Likewise. + * commands/ieee1275/halt.c (grub_halt_init, grub_halt_fini): + Likewise. + * commands/i386/pc/reboot.c (grub_reboot_init, grub_reboot_fini): + Likewise. + * commands/ieee1275/reboot.c (grub_reboot_init, grub_reboot_fini): + Likewise. + * disk/loopback.c (grub_loop_init, grub_loop_fini): Likewise. + * fs/affs.c (grub_affs_init, grub_affs_fini): Likewise. + * fs/ext2.c (grub_ext2_init, grub_ext2_fini): Likewise. + * fs/fat.c (grub_fat_init, grub_fat_fini): Likewise. + * fs/hfs.c (grub_hfs_init, grub_hfs_fini): Likewise. + * fs/iso9660.c (grub_iso9660_init, grub_iso9660_fini): Likewise. + * fs/jfs.c (grub_jfs_init, grub_jfs_fini): Likewise. + * fs/minix.c (grub_minix_init, grub_minix_fini): Likewise. + * fs/sfs.c (grub_sfs_init, grub_sfs_fini): Likewise. + * fs/ufs.c (grub_ufs_init, grub_ufs_fini): Likewise. + * fs/xfs.c (grub_xfs_init, grub_xfs_fini): Likewise. + * normal/main.c (grub_normal_init, grub_normal_fini): Likewise. + * partmap/amiga.c (grub_amiga_partition_map_init) + (grub_amiga_partition_map_fini): Likewise. + * partmap/apple.c (grub_apple_partition_map_init) + (grub_apple_partition_map_fini): Likewise. + * partmap/pc.c (grub_pc_partition_map_init) + (grub_pc_partition_map_fini): Likewise. + * partmap/sun.c (grub_sun_partition_map_init, + grub_sun_partition_map_fini): Likewise. + * term/terminfo.c (grub_terminal_init, grub_terminal_fini): + Likewise. + + * util/grub-emu.c: Include . + (main): Don't initialize and de-initialize any modules directly, + use `grub_init_all' and `grub_fini_all' instead. + + * term/i386/pc/vesafb.c (grub_vesafb_init): Renamed to + `grub_vesafb_mod_init'. + (grub_vesafb_fini): Renamed to `grub_vesafb_mod_fini'. Updated + all users. + * term/i386/pc/vga.c (grub_vga_init): Renamed to + `grub_vga_mod_init'. Updated all users. + (grub_vga_fini): Renamed to `grub_vga_mod_fini'. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `grub_emu_init.c'. + (grub_modules_init.lst, grub_modules_init.h, grub_emu_init.c): New + rules. + + * include/grub/dl.h (GRUB_MOD_INIT): Add argument `name'. + Generate a function to initialize the module in utilities. + Updated all callers. + (GRUB_MOD_FINI): Add argument `name'. Generate a function to + initialize the module in utilities. Updated all callers. + +2005-11-09 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_cls): Use both the ANSI + escape sequence and a literal ^L to clear the screen. + + * commands/ieee1275/suspend.c (grub_cmd_suspend): Clear the screen + when returning from Open Firmware. + +2005-11-09 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_width): New variable. + (grub_ofconsole_height): Likewise. + (grub_ofconsole_putchar): If `grub_curr_x' exceeds console width, + manually insert a '\n'. + (grub_ofconsole_getwh): Set and return `grub_ofconsole_width' and + `grub_ofconsole_height'. Return early if these are already set. + +2005-11-07 Vincent Pelletier + + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/test.c', `fs/affs.c', `fs/sfs.c', `fs/xfs.c', + `normal/execute.c', `normal/lexer.c', `io/gzio.c', + `kern/parser.c', `grub_script.tab.c', `normal/function.c' + and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES): New variable. + (test_mod_CFLAGS): Likewise. + (test_mod_LDFLAGS): Likewise. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + +2005-11-07 Marco Gerards + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/test.c', `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES): New variable. + (test_mod_CFLAGS): Likewise. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + +2005-11-06 Marco Gerards + + Add initial scripting support. + + * commands/test.c: New file. + * include/grub/script.h: Likewise. + * normal/execute.c: Likewise. + * normal/function.c: Likewise. + * normal/lexer.c: Likewise. + * normal/parser.y: Likewise. + * normal/script.c: Likewise. + + * configure.ac: Add `AC_PROG_YACC' test. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/test.c', + `normal/execute.c', `normal/lexer.c', `grub_script.tab.c', + `normal/function.c' and `normal/script.c'. + (normal_mod_SOURCES): `normal/execute.c', `normal/lexer.c', + `grub_script.tab.c', `normal/function.c' and `normal/script.c'. + (test_mod_SOURCES, test_mod_CFLAGS, test_mod_LDFLAGS): New + variables. + (pkgdata_MODULES): Add `test.mod'. + (grub_script.tab.c): New rule. + (grub_script.tab.h): Likewise. + + * include/grub/err.h (grub_err_t): Add `GRUB_ERR_TEST_FAILURE'. + + * include/grub/normal.h (grub_test_init): New prototype. + (grub_test_fini): Likewise. + + * normal/command.c: Include . + (grub_command_execute): Rewritten. + + * util/grub-emu.c (main): Call `grub_test_init' and + `grub_test_fini'. + +2005-11-03 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_get_rtc): Initialize `msecs' + to 0. + * term/ieee1275/ofconsole.c (grub_ofconsole_checkkey): Return -1 if + there are no pending characters. + +2005-11-03 Hollis Blanchard + + * kern/powerpc/ieee1275/openfw.c (grub_ieee1275_get_devname): Use + `grub_strndup' to drop device arguments. Replace unnecessary + `grub_strndup' with `grub_strdup'. + +2005-11-03 Hollis Blanchard + + * kern/term.c (grub_cls): Do not call grub_cur_term->cls() if the + `debug' environment variable has been set. + +2005-11-02 Hollis Blanchard + + * Makefile.in (install-local): Use $(DATA). + (uninstall): Likewise. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Move grub-mkimage... + (sbin_UTILITIES): ... to here. + (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): New variable. + * util/powerpc/ieee1275/grub-install.in: New file. + * util/powerpc/ieee1275/grub-mkimage.c (kernel_path): Remove + variable. + (add_segments): Call `grub_util_get_path'. + +2005-10-28 Yoshinori K. Okuji + + From Timothy Baldwin: + * commands/ls.c (grub_ls_list_files): Close FILE with + grub_file_close. + * kern/misc.c (grub_vsprintf): Terminate the string S with NUL. + +2005-10-24 Marco Gerards + + * include/grub/parser.h: New file. + + * kern/parser.c: Likewise. + + * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/parser.c'. + (grub_setup_SOURCES): Likewise. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (kernel_img_HEADERS): Add `parser.h'. + + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. + (grub_emu_SOURCES): Add `kern/parser.c'. + (grubof_SOURCES): Likewise. + + * conf/sparc64-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. + (grubof_SOURCES): Add `kern/parser.c'. + + * include/grub/misc.h (grub_split_cmdline): Removed prototype. + + * kern/misc.c (grub_split_cmdline): Removed function. + + * kern/rescue.c: Include . + (grub_enter_rescue_mode): Use `grub_parser_split_cmdline' instead + of `grub_split_cmdline'. + + * normal/command.c: Include . + (grub_command_execute): Use `grub_parser_split_cmdline' instead + of `grub_split_cmdline'. + + * normal/completion.c: Include . + (cmdline_state): New variable. + (iterate_dir): End the filename with a quote depending on the + command line state. + (get_state): new function. + (grub_normal_do_completion): Use `grub_parser_split_cmdline' to + split the arguments and determine the current argument. When the + argument string is not quoted, escape all spaces. + +2005-10-23 Vincent Pelletier + + * normal/sparc64/setjmp.S: New file. + +2005-10-23 Vincent Pelletier + + * include/grub/sparc64/libgcc.h: New file. + * conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Remove -Av9. + (normal_mod_SOURCES): Use normal/sparc64/setjmp.S instead of + normal/sparc64/setjmp.c. + +2005-10-23 Vincent Pelletier + + * kern/sparc64/dl.c: Rewritten for SPARCV9 ELF. + * kern/sparc64/cache.S: New file. + * kern/sparc64/cache.c: Removed. + * conf/sparc64-ieee1275.rmk (COMMON_ASFLAGS): Add -Av9. + (COMMON_CFLAGS): Add -mno-app-regs. Remove -mcpu=v9 and + -mtune=ultrasparc. + (COMMON_LDFLAGS): Add -melf64_sparc. + (grubof_HEADERS): Add sparc64/libgcc.h and machine/kernel.h. + (grubof_SOURCES): Use cache.S instead of cache.c. + (grubof_LDFLAGS): Add -mno-app-regs. Replace "-Xlinker + --oformat -Xlinker elf64-sparc" by "-Bstatic,-melf64_sparc". + (pkgdata_MODULES): Uncomment. Leave linux.mod and _linux.mod + commented though. + (normal_mod_SOURCES): Add normal/completion.c and normal/misc.c. + (_linux_mod_SOURCES, _linux_mod_CFLAGS, linux_mod_SOURCES) + (linux_mod_CFLAGS): Commented out. + (_linux_mod_LDFLAGS, linux_mod_LDFLAGS): New macro, commented + out because module isn't built. + (fshelp_mod_LDFLAGS, fat_mod_LDFLAGS, ext2_mod_LDFLAGS) + (ufs_mod_LDFLAGS, minix_mod_LDFLAGS, hfs_mod_LDFLAGS) + (jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS, normal_mod_LDFLAGS) + (hello_mod_LDFLAGS, boot_mod_LDFLAGS, terminal_mod_LDFLAGS) + (ls_mod_LDFLAGS, cmp_mod_LDFLAGS, cat_mod_LDFLAGS) + (font_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS) + (pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS) + (suspend_mod_LDFLAGS, reboot_mod_LDFLAGS, halt_mod_LDFLAGS) + (help_mod_LDFLAGS, default_mod_LDFLAGS, timeout_mod_LDFLAGS) + (configfile_mod_LDFLAGS, search_mod_LDFLAGS, xfs_mod_SOURCES) + (xfs_mod_CFLAGS, xfs_mod_LDFLAGS, affs_mod_SOURCES) + (affs_mod_CFLAGS, affs_mod_LDFLAGS, sfs_mod_SOURCES) + (sfs_mod_CFLAGS, sfs_mod_LDFLAGS, gzio_mod_SOURCES) + (gzio_mod_CFLAGS, gzio_mod_LDFLAGS): New macro. + +2005-10-20 Yoshinori K. Okuji + + * util/i386/pc/grub-probefs.c (main): Call grub_xfs_init and + grub_xfs_fini. Do not call grub_hfs_init or grub_hfs_fini any + longer, because HFS should not be used on PC. + +2005-10-20 Timothy Baldwin + + * io/gzio.c (grub_gzio_read): Use OFFSET instead of FILE->OFFSET + consistently within the loop. + +2005-10-15 Marco Gerards + + * fs/xfs.c (grub_xfs_iterate_dir): Detect an error if part of a + directory can not be read. + +2005-10-15 Yoshinori K. Okuji + + * configure.ac (AC_INIT): Increase the version number to 1.91. + + * DISTLIST: Added include/grub/terminfo.h, include/grub/tparm.h, + include/grub/i386/pc/serial.h, term/terminfo.c, term/tparm.c and + term/i386/pc/serial.c. + +2005-10-15 Yoshinori K. Okuji + + * kern/file.c (grub_file_seek): Seeking to an offset equal to a + file size must be permitted. + + * kern/i386/pc/startup.S (multiboot_trampoline): Fix a mistake + between %ah and %al. + +2005-10-15 Yoshinori K. Okuji + + * fs/xfs.c (grub_xfs_iterate_dir): Change the type of BLK to + grub_uint64_t. + Call the hook with a NUL-terminated filename. + (grub_xfs_mount): Use grub_be_to_cpu32 instead of + grub_cpu_to_be32. + + * kern/term.c (cursor_state): New variable. + (grub_term_set_current): Reset the cursor state on a new + terminal. + (grub_setcursor): Rewritten to use CURSOR_STATE. + (grub_getcursor): New function. + + * include/grub/term.h (grub_getcursor): New prototype. + + * io/gzio.c (test_header): Align BUF for accessing it as 32-bit + integers on ARM. Reported by Timothy Baldwin + . + +2005-10-11 Marco Gerards + + * fs/sfs.c (grub_sfs_open): Don't free `data->label' if it is not + allocated. + (grub_sfs_dir): Likewise. + +2005-10-09 Marco Gerards + + Add support for the SFS filesystem. + + * fs/sfs.c: New file. + + * DISTLIST: Added `fs/sfs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/sfs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `sfs.mod'. + (sfs_mod_SOURCES): New variable. + (sfs_mod_CFLAGS): Likewise. + (sfs_mod_LDFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/sfs.c'. + (pkgdata_MODULES): Add `sfs.mod'. + (sfs_mod_SOURCES): New variable. + (sfs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_sfs_init' and + `grub_sfs_fini'. + + * include/grub/fs.h (grub_sfs_init): New prototype. + (grub_sfs_fini): Likewise. + +2005-10-07 Marco Gerards + + Add support for the AFFS filesystem. + + * fs/affs.c: New file. + + * DISTLIST: Added `fs/affs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/affs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `affs.mod'. + (affs_mod_SOURCES): New variable. + (affs_mod_CFLAGS): Likewise. + (affs_mod_LDFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/affs.c'. + (pkgdata_MODULES): Add `affs.mod'. + (affs_mod_SOURCES): New variable. + (affs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_affs_init' and + `grub_affs_fini'. + + * include/grub/fs.h (grub_affs_init): New prototype. + (grub_affs_fini): Likewise. + +2005-10-01 Marco Gerards + + * fs/xfs.c (grub_xfs_iterate_dir): Add parentheses. + +2005-10-01 Marco Gerards + + * configure.ac: Accept `x86_64' as host_cpu. In that case add + `-m32' to CFLAGS. + + * genmk.rb (class PModule): Always use `$(#{prefix}_LDFLAGS)' when + linking. + + * conf/i386-pc.rmk (COMMON_CFLAGS): Add `-m32'. + (COMMON_LDFLAGS): New variable. + (kernel_img_LDFLAGS): Include `COMMON_FLAGS'. + (_chain_mod_LDFLAGS, fshelp_mod_LDFLAGS, fat_mod_LDFLAGS) + (ext2_mod_LDFLAGS, ufs_mod_LDFLAGS, minix_mod_LDFLAGS) + (hfs_mod_LDFLAGS, jfs_mod_LDFLAGS, iso9660_mod_LDFLAGS) + (xfs_mod_LDFLAGS, _linux_mod_LDFLAGS, linux_mod_LDFLAGS) + (normal_mod_LDFLAGS, hello_mod_LDFLAGS, boot_mod_LDFLAGS) + (terminal_mod_LDFLAGS, ls_mod_LDFLAGS, cmp_mod_LDFLAGS) + (cat_mod_LDFLAGS, help_mod_LDFLAGS, reboot_mod_LDFLAGS) + (halt_mod_LDFLAGS, vga_mod_LDFLAGS, font_mod_LDFLAGS) + (terminfo_mod_LDFLAGS, serial_mod_LDFLAGS, _multiboot_mod_LDFLAGS) + (multiboot_mod_LDFLAGS, amiga_mod_LDFLAGS, apple_mod_LDFLAGS) + (pc_mod_LDFLAGS, sun_mod_LDFLAGS, loopback_mod_LDFLAGS) + (default_mod_LDFLAGS, timeout_mod_LDFLAGS, configfile_mod_LDFLAGS) + (vbe_mod_LDFLAGS, vesafb_mod_LDFLAGS, vbeinfo_mod_LDFLAGS) + (vbetest_mod_LDFLAGS, search_mod_LDFLAGS, gzio_mod_LDFLAGS): New + variables. + (normal_mod_ASFLAGS): Add `-m32'. + + * include/grub/types.h (grub_host_addr_t, grub_host_off_t) + (grub_host_size_t, grub_host_ssize_t): New types. + (grub_addr_t, grub_off_t, grub_size_t, grub_ssize_t): Make type + dependent of `GRUB_CPU_SIZEOF_VOID_P' instead on + `GRUB_HOST_SIZEOF_VOID_P'. + + * include/grub/kernel.h (struct grub_module_header): Type of + member offset changed to `grub_host_off_t'. Type of member size + changed to `grub_host_size_t'. + (struct grub_module_info): Type of member offset changed to + `grub_host_off_t'. Type of member size changed to + `grub_host_size_t'. + +2005-09-29 Yoshinori K. Okuji + + Make GRUB's kernel compliant to Multiboot Specification. + + * kern/i386/pc/startup.S (multiboot_header): New label. + (multiboot_entry): Likewise. + (multiboot_trampoline): Likewise. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Increased to 0x4A0. + + * fs/xfs.c (grub_xfs_iterate_dir): Fix a syntax error. You may not + put parentheses after a question mark. + [!GRUB_UTIL] (my_mod): New variable. + + * util/grub-emu.c (main): Call grub_xfs_init and grub_xfs_fini. + +2005-09-28 Marco Gerards + + Adds support for the XFS filesystem. Btrees are not supported + yet. + + * fs/xfs.c: New file. + + * DISTLIST: Added `fs/xfs.c'. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `fs/xfs.c'. + (grub_probefs_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `xfs.mod'. + (xfs_mod_SOURCES): New variable. + (xfs_mod_CFLAGS): Likewise. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add `fs/xfs.c'. + (pkgdata_MODULES): Add `xfs.mod'. + (xfs_mod_SOURCES): New variable. + (xfs_mod_CFLAGS): Likewise. + + * util/grub-emu.c (main): Call `grub_xfs_init' and + `grub_xfs_fini'. + + * include/grub/fs.h (grub_xfs_init): New prototype. + (grub_xfs_fini): Likewise. + + +2005-09-18 Vesa Jaaskelainen + + * video/i386/pc/vbe.c (grub_vbe_set_video_mode): In indexed + color modes, allow greater than 16 colors to be configured as + a default palette. + +2005-09-03 Yoshinori K. Okuji + + * normal/completion.c (complete_arguments): Add the qualifier + const into OPTIONS. + + From Omniflux : + * include/grub/terminfo.h: New file. + * include/grub/tparm.h: Likewise. + * include/grub/i386/pc/serial.h: Likewise. + * term/terminfo.c: Likewise. + * term/tparm.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * conf/i386-pc.rmk (pkgdata_MODULES): Added terminfo.mod and + serial.mod. + (terminfo_mod_SOURCES): New variable. + (terminfo_mod_CFLAGS): Likewise. + (serial_mod_SOURCES): Likewise. + (serial_mod_CFLAGS): Likewise. + +2005-08-31 Yoshinori K. Okuji + + * DISTLIST: Replaced boot/powerpc/ieee1275/crt0.S and + boot/powerpc/ieee1275/cmain.c with kern/powerpc/ieee1275/crt0.S + and kern/powerpc/ieee1275/cmain.c, respectively. + + * boot/powerpc/ieee1275/crt0.S: Moved to ... + * kern/powerpc/ieee1275/crt0.S: ... here. + + * boot/powerpc/ieee1275/cmain.c: Moved to ... + * kern/powerpc/ieee1275/cmain.c: ... here. + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Use + kern/powerpc/ieee1275/crt0.S and kern/powerpc/ieee1275/cmain.c + instead of boot/powerpc/ieee1275/crt0.S and + boot/powerpc/ieee1275/cmain.c, respectively. + + * boot/i386/pc/boot.S (lba_mode): Do not store the total number of + sectors. It was not used anyway. + +2005-08-30 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): Fix + `unused parameter' warning. + +2005-08-30 Hollis Blanchard + + * term/ieee1275/ofconsole.c (grub_ofconsole_getcharwidth): New + function. + (grub_ofconsole_term): Specify grub_ofconsole_getcharwidth as + getcharwidth. + +2005-08-28 Marco Gerards + + * include/grub/normal.h (enum grub_completion_type): Added + `GRUB_COMPLETION_TYPE_ARGUMENT'. + + * normal/cmdline.c (print_completion): Handle + the `GRUB_COMPLETION_TYPE_ARGUMENT' type. + * normal/menu_entry.c (store_completion): Likewise. + + * normal/completion.c (complete_arguments): New function. + (grub_normal_do_completion): Call `complete_arguments' when the + current words start with a dash. + +2005-08-27 Marco Gerards + + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Fix typo (use + `gzio.mod' instead of `io.mod'). + +2005-08-22 Yoshinori K. Okuji + + * gendistlist.sh (EXTRA_DISTFILES): Added genfslist.sh. + (DISTDIRS): Added io and video. + Rewrite the search routine to make an output consistently. + + * DISTLIST: Added conf/sparc64-ieee1275.mk, + conf/sparc64-ieee1275.rmk, include/grub/gzio.h, + include/grub/ieee1275/ieee1275.h, include/grub/ieee1275/ofdisk.h, + io/gzio.c, kern/sparc64/cache.c, kern/sparc64/dl.c, + kern/sparc64/ieee1275/init.c, kern/sparc64/ieee1275/openfw.c and + util/powerpc/ieee1275/misc.c. + + * include/grub/gzio.h: New file. + * io/gzio.c: Likewise. + + * kern/file.c (grub_file_close): Call grub_device_close only if + FILE->DEVICE is not NULL. + + * include/grub/mm.h [!NULL] (NULL): New macro. + + * include/grub/err.h (GRUB_ERR_BAD_GZIP_DATA): New constant. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added io/gzip.c. + (pkgdata_MODULES): Added gzio.mod. + (gzio_mod_SOURCES): New variable. + (gzio_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added io/gzip.c. + (pkgdata_MODULES): Added gzio.mod. + (gzio_mod_SOURCES): New variable. + (gzio_mod_CFLAGS): Likewise. + + * commands/cat.c: Include grub/gzio.h. + (grub_cmd_cat): Use grub_gzfile_open instead of + grub_file_open. + + * commands/cmp.c: Include grub/gzio.h. + (grub_cmd_cmp): Use grub_gzfile_open instead of + grub_file_open. + + * loader/i386/pc/multiboot.c: Include grub/gzio.h. + (grub_rescue_cmd_multiboot): Use grub_gzfile_open instead of + grub_file_open. + (grub_rescue_cmd_module): Likewise. + +2005-08-21 Vincent Pelletier + + * conf/sparc64-ieee1275.rmk (grubof_SOURCES): The first file must be + kern/sparc64/ieee1275/init.c because it contains _start. + * conf/sparc64-ieee1275.mk: Generated from conf/sparc64-ieee1275.rmk. + +2005-08-21 Vincent Pelletier + + * configure.ac: Add support for sparc64 host with ieee1275 + firmware. + * configure: Generated from configure.ac. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Use grub_ssize_t + instead of int. + (grub_ofdisk_read): Likewise. + (grub_ofdisk_open): Use %p to print pointer values, and cast the + pointers as (void *) to remove a warning. + (grub_ofdisk_close): Likewise. + (grub_ofdisk_read): Likewise. + * kern/ieee1275/ieee1275.c (grub_ieee1275_exit): This never + returns, so make it return void to remove a warning. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_exit): + Corresponding prototype change. + * kern/mm.c (grub_mm_init_region): Use %p to print pointer + values, and cast the pointers as (void *) to remove a warning. + (grub_mm_dump): Likewise. + * conf/sparc64-ieee1275.mk: New file. + * conf/sparc64-ieee1275.rmk: Likewise. + * include/grub/sparc64/setjmp.h: Likewise. + * include/grub/sparc64/types.h: Likewise. + * include/grub/sparc64/ieee1275/console.h: Likewise. + * include/grub/sparc64/ieee1275/ieee1275.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/time.h: Likewise. + * kern/sparc64/cache.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * kern/sparc64/ieee1275/init.c: Likewise. + * kern/sparc64/ieee1275/openfw.c: Likewise. + +2005-08-21 Yoshinori K. Okuji + + * util/console.c (grub_ncurses_putchar): If C is greater than + 0x7f, set C to a question mark. + (grub_ncurses_getcharwidth): New function. + (grub_ncurses_term): Specify grub_ncurses_getcharwidth as + getcharwidth. + + * normal/menu.c (print_entry): Made aware of Unicode. First, + convert TITLE to UCS-4, and predict the cursor position by + grub_getcharwidth. + + * include/grub/misc.h (grub_utf8_to_ucs4): Specify the qualifier + const to SRC. + * kern/misc.c (grub_utf16_to_utf8): Likewise. + +2005-08-20 Yoshinori K. Okuji + + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Specify + the boot file by the option BOOT_IMAGE. Use grub_stpcpy instead of + grub_strcat. + + * loader/i386/pc/linux.c (grub_rescue_cmd_linux): Specify the boot + file by the option BOOT_IMAGE. Use grub_stpcpy instead of + grub_strcpy and grub_strlen. Take it into account that a space + character is inserted as a delimiter. + +2005-08-20 Yoshinori K. Okuji + + * partmap/pc.c (pc_partition_map_iterate): Include the value of an + invalid magic in the error. + + * commands/search.c: New file. + + * util/grub-emu.c (main): Call grub_search_init and + grub_search_fini. + + * kern/rescue.c (grub_rescue_print_disks): Removed. + (grub_rescue_print_devices): New function. + (grub_rescue_cmd_ls): Use grub_device_iterate with + grub_rescue_print_devices instead of grub_disk_dev_iterate with + grub_rescue_print_disks. + + * kern/partition.c (grub_partition_iterate): Return the result of + PARTMAP->ITERATE instead of GRUB_ERRNO. + + * kern/device.c: Include grub/partition.h. + (grub_device_iterate): New function. + + * include/grub/partition.h (grub_partition_iterate): Return int + instead of grub_err_t. + + * include/grub/normal.h [GRUB_UTIL] (grub_search_init): New + prototype. + [GRUB_UTIL] (grub_search_fini): Likewise. + + * include/grub/device.h (grub_device_iterate): New prototype. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + commands/search.c. + (pkgdata_MODULES): Added search.mod. + (search_mod_SOURCES): New variable. + (search_mod_CFLAGS): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/search.c. + (pkgdata_MODULES): Added search.mod. + (search_mod_SOURCES): New variable. + (search_mod_CFLAGS): Likewise. + + * commands/ls.c (grub_ls_list_disks): Renamed to ... + (grub_ls_list_devices): ... this, and use grub_device_iterate. + All callers changed. + + * DISTLIST: Added commands/search.c. + +2005-08-20 Yoshinori K. Okuji + + * kern/term.c (grub_putchar): Use grub_utf8_to_ucs4 for the + conversion. + (grub_getcharwidth): New function. + + * kern/misc.c (grub_utf8_to_ucs4): New function. + + * include/grub/term.h (struct grub_term): Added a new member + "getcharwidth". + (grub_getcharwidth): New prototype. + + * include/grub/misc.h (grub_utf8_to_ucs4): New prototype. + + * term/i386/pc/console.c (map_char): New function. Segregated from + grub_console_putchar. + (grub_console_putchar): Use map_char. + (grub_console_getcharwidth): New function. + (grub_console_term): Specified grub_console_getcharwidth as + getcharwidth. + + * term/i386/pc/vga.c (grub_vga_getcharwidth): New function. + (grub_vga_term): Specified grub_vga_getcharwidth as getcharwidth. + + * term/i386/pc/vesafb.c (grub_virtual_screen_setup): Return + GRUB_ERRNO. + (grub_vesafb_init): Do not use RC. Instead, use GRUB_ERRNO. Rely + on grub_strtoul completely. + (write_char): Declare local variables in the beginning of the + function. + (grub_vesafb_getcharwidth): New function. + (grub_vesafb_term): Specified grub_vesafb_getcharwidth as + getcharwidth. + +2005-08-19 Yoshinori K. Okuji + + * DISTLIST: Replace commands/i386/pc/vbe_list_modes.c and + commands/i386/pc/vbe_test.c with commands/i386/pc/vbeinfo.c and + commands/i386/pc/vbetest.c. + + * video/i386/pc/vbe.c (grub_vbe_probe): If INFOBLOCK is not NULL, + call grub_vbe_get_controller_info again, because the returned + information is volatile. + (grub_vbe_set_video_mode): Mostly rewritten. + (grub_vbe_get_video_mode): Use grub_vbe_probe and use + grub_vbe_status_t correctly. + (grub_vbe_get_video_mode_info): Likewise. + (grub_vbe_set_pixel_rgb): Use a switch statement rather than + several if statements. + + * commands/i386/pc/vbe_list_modes.c: Renamed to ... + * commands/i386/pc/vbeinfo.c: ... this. + + * commands/i386/pc/vbe_test.c: Renamed to ... + * commands/i386/pc/vbetest.c: ... this. + + * commands/i386/pc/vbeinfo.c (grub_cmd_vbe_list_modes): Renamed to + ... + (grub_cmd_vbeinfo): ... this. Save video modes before + iterating. Skip a video mode, if it is not available, not enough + information is given or it is monochrome. Show the memory + model. Leave the interpretation of MODEVAR to grub_strtoul + completely. + (GRUB_MOD_INIT): Rename vbe_list_modes to vbeinfo. + (GRUB_MOD_FINI): Likewise. + + * commands/i386/pc/vbetest.c (grub_cmd_vbe_test): Renamed to ... + (grub_cmd_vbetest): ... this. Don't print unnecessarily. Use + grub_err_t instead of grub_uint32_t. Don't use SPTR. Remove a + duplicated grub_env_get. Leave the interpretation of MODEVAR to + grub_strtoul completely. + (real2pm): Removed. + (GRUB_MOD_INIT): Rename vbe_test to vbetest. + (GRUB_MOD_FINI): Likewise. + + * normal/misc.c: Include grub/mm.h. + + * conf/i386-pc.rmk (pkgdata_MODULES): Replaced vbe_test.mod and + vbe_list_modes with vbetest.mod and vbeinfo.mod. + (vbe_list_modes_mod_SOURCES): Removed. + (vbe_list_modes_mod_CFLAGS): Likewise. + (vbe_test_mod_SOURCES): Likewise. + (vbe_test_mod_CFLAGS): Likewise. + (vbeinfo_mod_SOURCES): New variable. + (vbeinfo_mod_CFLAGS): Likewise. + (vbetest_mod_SOURCES): Likewise. + (vbetest_mod_CFLAGS): Likewise. + +2005-08-18 Yoshinori K. Okuji + + * normal/misc.c: New file. + + * DISTLIST: Added normal/misc.c. + + * partmap/amiga.c (amiga_partition_map_iterate): Add an argument + DISK to HOOK. Call HOOK with DISK. + * partmap/apple.c (apple_partition_map_iterate): Likewise. + * partmap/pc.c (pc_partition_map_iterate): Likewise. + * partmap/sun.c (sun_partition_map_iterate): Likewise. + + * normal/menu_entry.c (struct screen): Added a new member + "completion_shown". + (completion_buffer): New global variable. + (make_screen): Set SCREEN->COMPLETION_SHOWN to zero. + (store_completion): New function. + (complete): Likewise. + (clear_completions): Likewise. + (grub_menu_entry_run): If SCREEN->COMPLETION_SHOWN is non-zero, + call clear_completions and reset SCREEN->COMPLETION_SHOWN. If C is + a tab, call complete. + + * normal/completion.c (disk_dev): Removed. + (print_simple_completion): Likewise. + (print_partition_completion): Likewise. + (print_func): New global variable. + (add_completion): Do not take the arguments WHAT or PRINT any + longer. Added a new argument TYPE. Instead of printing directly, + call PRINT_FUNC if not NULL. + All callers changed. + (complete_device): Use a local variable DEV instead of + DISK_DEV. Do not move CURRENT_WORD to the end of a device name. + (grub_normal_do_completion): Take a new argument HOOK. Do not + initialize DISK_DEV. Initialize PRINT_FUNC to HOOK. If RET is an + empty string, return NULL instead. + All callers changed. + + * normal/cmdline.c (print_completion): New function. + + * kern/partition.c (grub_partition_iterate): Add an argument DISK + to HOOK. + All callers changed. + + * kern/disk.c (grub_print_partinfo): Removed. + + * include/grub/partition.h (struct grub_partition_map): Add a new + argument DISK into HOOK of ITERATE. + (grub_partition_iterate): Add a new argument DISK to HOOK. + + * include/grub/normal.h (enum grub_completion_type): New enum. + (grub_completion_type_t): New type. + (GRUB_COMPLETION_TYPE_COMMAND): New constant. + (GRUB_COMPLETION_TYPE_DEVICE): Likewise. + (GRUB_COMPLETION_TYPE_PARTITION): Likewise. + (GRUB_COMPLETION_TYPE_FILE): Likewise. + (grub_normal_do_completion): Added a new argument HOOK. + (grub_normal_print_device_info): New prototype. + + * include/grub/disk.h (grub_print_partinfo): Removed. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added normal/misc.c. + (normal_mod_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * commands/ls.c (grub_ls_list_disks): Use + grub_normal_print_device_info instead of grub_print_partinfo. Free + PNAME. + (grub_ls_list_files): Use grub_normal_print_device_info instead of + duplicating the code. + +2005-08-16 Vesa Jaaskelainen + + * commands/i386/pc/vbe_list_modes.c: Update source formatting to + follow GCS more precisely. + * commands/i386/pc/vbe_test.c: Likewise. + * include/grub/i386/pc/vbe.h: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + +2005-08-16 Vesa Jaaskelainen + + * DISTLIST: Added term/i386/pc/vesafb.c + DISTLIST: Added video/i386/pc/vbe.c + DISTLIST: Added commands/i386/pc/vbe_list_modes.c. + DISTLIST: Added commands/i386/pc/vbe_test.c. + * commands/i386/pc/vbe_list_modes.c: New file. + * commands/i386/pc/vbe_test.c: Likewise. + * term/i386/pc/vesafb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * include/grub/i386/pc/vbe.h (GRUB_VBE_DEFAULT_VIDEO_MODE): Added define. + (grub_vbe_probe) Added prototype. + (grub_vbe_set_video_mode) Likewise. + (grub_vbe_get_video_mode) Likewise. + (grub_vbe_get_video_mode_info) Likewise. + (grub_vbe_set_pixel_rgb) Likewise. + (grub_vbe_set_pixel_index) Likewise. + * conf/i386-pc.rmk (pkgdata_MODULES): Added vbe.mod. + (pkgdata_MODULES): Added vesafb.mod. + (pkgdata_MODULES): Added vbe_list_modes.mod. + (pkgdata_MODULES): Added vbe_test.mod. + (vbe_mod_SOURCES): Added. + (vbe_mod_CFLAGS): Likewise. + (vesafb_mod_SOURCES): Likewise. + (vesafb_mod_CFLAGS): Likewise. + (vbe_list_modes_mod_SOURCES): Likewise. + (vbe_list_modes_mod_CFLAGS): Likewise. + (vbe_test_mod_SOURCES): Likewise. + (vbe_test_mod_CFLAGS): Likewise. + +2005-08-14 Yoshinori K. Okuji + + * normal/command.c (grub_command_execute): If INTERACTIVE is + false and GRUB_COMMAND_FLAG_NO_ECHO is not specified, print + CMDLINE. Disable the pager if INTERACTIVE is true. + All callers are changed. + + * normal/main.c (grub_normal_execute): Read command.lst and fs.lst + before reading a config file. + * normal/main.c (read_config_file): Even if a command is not + found, register it if it is within an entry. + + * util/grub-emu.c: Include sys/types.h and unistd.h. + (options): Added --hold. + (struct arguments): Added a new member "hold". + (parse_opt): If KEY is 'H', set ARGS->HOLD to ARG or -1 if ARG is + missing. + (main): Initialize ARGS.HOLD to zero. Wait until ARGS.HOLD is + cleared by a debugger, if it is not zero. + + * include/grub/normal.h (grub_command_execute): Add an argument + INTERACTIVE. + +2005-08-14 Vesa Jaaskelainen + + * DISTLIST: Added include/grub/i386/pc/vbe.h. + +2005-08-13 Yoshinori K. Okuji + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): Replace the test + program with another one, because the old one didn't detect a bug + in gcc-3.4. Always use regparm 2, because the new test is still + not enough for gcc-4.0. Someone must investigate a simple test + case which detects a bug in gcc-4.0. + +2005-08-12 Yoshinori K. Okuji + + * DISTLIST: Added normal/completion.c. + + * normal/completion.c: New file. + + * term/i386/pc/console.c (grub_console_getwh): New function. + (grub_console_term): Assign grub_console_getwh to getwh. + + * normal/cmdline.c (grub_tab_complete): Removed. Now the same + function is defined in normal/completion.c as + grub_normal_do_completion. + (grub_cmdline_get): Use grub_normal_do_completion instead of + grub_tab_complete. + + * kern/partition.c (grub_partition_map_iterate): Return 1 if HOOK + returns non-zero, otherwise return 0. + (grub_partition_iterate): First, probe the partition map. Then, + call ITERATE only for this partition map. + + * kern/misc.c (grub_strncmp): Rewritten. + + * kern/disk.c (grub_disk_dev_iterate): Return 1 if P->ITERATE + returns non-zero. Otherwise return 0. + + * include/grub/partition.h (grub_partition_map_iterate): Return + int instead of void. + + * include/grub/normal.h (grub_normal_do_completion): New prototype. + + * include/grub/misc.h (grub_strncmp): Change the type of N to + grub_size_t. + + * include/grub/disk.h (grub_disk_dev_iterate): Return int instead + of void. + + * normal/menu.c (draw_border): Cast GRUB_TERM_BORDER_WIDTH to + unsigned explicitly before comparing it with I. + + * kern/main.c (grub_env_write_root): Add the attribute unused into + VAR. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + normal/completion.c. + (normal_mod_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + + * normal/command.c (grub_iterate_commands): If ITERATE returns + non-zero, return one immediately. + +2005-08-09 Vesa Jaaskelainen + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vbe.h. + * kern/i386/pc/startup.S: Updated Global Descriptor table's + descriptions. + (grub_vbe_get_controller_info): New function. + (grub_vbe_get_mode_info): Likewise. + (grub_vbe_set_mode): Likewise. + (grub_vbe_get_mode): Likewise. + (grub_vbe_set_memory_window): Likewise. + (grub_vbe_get_memory_window): Likewise. + (grub_vbe_set_scanline_length): Likewise. + (grub_vbe_get_scanline_length): Likewise. + (grub_vbe_set_display_start): Likewise. + (grub_vbe_get_display_start): Likewise. + (grub_vbe_set_palette_data): Likewise. + * include/grub/i386/pc/vbe.h: New file. + +2005-08-08 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced + kern/ieee1275/of.c with kern/ieee1275/ieee1275.c. + * DISTLIST: Likewise. + * kern/ieee1275/of.c: Moved to ... + * kern/ieee1275/ieee1275.c: ... here. + +2005-08-08 Hollis Blanchard + + * term/ieee1275/ofconsole.c: Include . + (grub_ofconsole_getwh): Cast -1 to type grub_ieee1275_ihandle_t. + Pass 0 as `end' parameter to grub_strtoul(). + +2005-08-08 Hollis Blanchard + + * include/grub/powerpc/ieee1275/console.h: Do not include + . Do not include . Remove ASM_FILE + ifdef. + (grub_console_cur_color): Remove i386-specific prototype. + (grub_console_real_putchar): Likewise. + (grub_console_checkkey): Likewise. + (grub_console_getkey): Likewise. + (grub_console_getxy): Likewise. + (grub_console_gotoxy): Likewise. + (grub_console_cls): Likewise. + (grub_console_setcursor): Likewise. + * kern/powerpc/ieee1275/init.c: Don't include . + Include . + * term/ieee1275/ofconsole.c: Likewise. + +2005-08-08 Yoshinori K. Okuji + + * Makefile.in (LIBLZO): New variable. + + * configure.ac: Check for LZO version 2. + + * util/i386/pc/grub-mkimage.c [HAVE_LZO_LZO1X_H]: Include + lzo/lzo1x.h instead of lzo1x.h. + + * conf/i386-pc.rmk (grub_mkimage_LDFLAGS): Use $(LIBLZO) instead + of -llzo. + + * util/i386/pc/grub-setup.c (main): Do not free PREFIX + twice. Reported by Vladimir Serbinenko . + + * partmap/pc.c (pc_partition_map_probe): Restore P->DATA after + copying the data from PARTITION to P. + +2005-08-07 Yoshinori K. Okuji + + * kern/rescue.c (grub_rescue_cmd_rmmod): If the reference count is + negative, unload the module. + + * util/i386/pc/grub-setup.c (setup): The name of the PC partition + map is "pc_partition_map" but not "pc". + (usage): Fix the description. The options are --boot-image and + --core-image but not --boot-file or --core-file. + (main): If not specified explicitly, make BOOT_FILE and CORE_FILE + based on DEFAULT_BOOT_FILE and DEFAULT_CORE_FILE with DIR or + DEFAULT_DIRECTORY. + + * util/i386/pc/grub-install.in: Do not specify --boot-file or + --core-file. Specify INSTALL_DEVICE as an argument. + + * util/console.c: Include config.h. + [HAVE_NCURSeS_CURSES_H]: Include ncurses/curses.h. + [HAVE_NCURSES_H]: Include ncurses.h. + [HAVE_CURSES_H]: Include curses.h. + [!A_NORMAL] (A_NORMAL): Defined as zero. + [!A_STANDOUT] (A_STANDOUT): Likewise. + + * conf/i386-pc.rmk (grub_emu_LDFLAGS): Use $(LIBCURSES) instead of + -lncurses. + * conf/powerpc-ieee1275.rmk (grub_emu_LDFLAGS): Likewise. + + * configure.ac: Check for curses libraries and headers. + + * Makefile.in (LIBCURSES): New variable. + + * genmk.rb (Script::rule): Set the executable bits. + + * util/i386/pc/biosdisk.c (grub_util_biosdisk_get_grub_dev): The + name of the PC partition map is "pc_partition_map" but not "pc". + +2005-08-07 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (grub_probefs): New variable. + (modules): Likewise. + (usage): Added descriptions for --modules and --grub-probefs. + Handle --modules and --grub-probefs. Save the arguments in MODULES + and GRUB_PROBEFS, respectively. + Auto-detect a filesystem module against GRUBDIR. If the result is + empty and modules are not specified explicitly, abort the + installation. Add the result to MODULES. + + * DISTLIST: Removed boot/powerpc/ieee1275/ieee1275.c, + disk/powerpc/ieee1275/ofdisk.c, + include/grub/powerpc/ieee1275/init.h and + term/powerpc/ieee1275/ofconsole.c. + Added disk/ieee1275/ofdisk.c, kern/ieee1275/of.c and + term/ieee1275/ofconsole.c. + + * include/grub/powerpc/ieee1275/console.h: Resurrected. + + * COPYING: Upgraded to the latest version. Only the address of the + FSF office has changed. + +2005-08-07 Yoshinori K. Okuji + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Replaced + kern/ieee1275.c with kern/ieee1275/of.c. + + * kern/ieee1275.c: Moved to ... + * kern/ieee1275/of.c: ... here. + +2005-08-06 Yoshinori K. Okuji + + * conf/i386-pc.rmk (kernel_img_HEADERS): Reordered for + readability. + + * config.guess: Updated to the latest version from gnulib. + * config.sub: Likewise. + * install.sh: Likewise. + * mkinstalldirs: Likewise. + + * include/grub/console.h: Removed. This file is arch-specific. Do + not put this in include/grub. + + * include/grub/i386/pc/console.h: Resurrected. + + * util/console.c: Include grub/machine/console.h instead of + grub/console.h. + * util/grub-emu.c: Likewise. + +2005-08-04 Marco Gerards + + * kern/term.c (grub_putcode): Use `grub_getwh' instead of + hardcoded value. + + From Vincent Pelletier + * include/grub/term.h (GRUB_TERM_WIDTH, GRUB_TERM_HEIGHT): + Redefined to use grub_getwh. + (grub_term): New member named getwh. + (grub_getwh): New prototype. + * kern/term.c (grub_getwh): New function. + * term/i386/pc/console.c (grub_console_getwh): New function. + (grub_console_term): New member `getwh'. + * term/i386/pc/vga.c (grub_vga_getwh): New function. + (grub_vga_term): New member `getwh'. + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Use + grub_ssize_t. + (grub_ofconsole_getw): New function. + (grub_ofconsole_init): Use grub_ssize_t and unsigned char. + (grub_ofconsole_term): New field named getwh and new initial + value. + +2005-08-03 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h: Move ... + * include/grub/ieee1275/ieee1275.h: ... to here. All users updated. + Move `abort', `grub_reboot', and `grub_halt' prototypes ... + * include/grub/powerpc/ieee1275/kernel.h: ... to here. + * commands/ieee1275/halt.c: Include instead + of . + * commands/ieee1275/reboot.c: Likewise. + * boot/powerpc/ieee1275/ieee1275.c: Move ... + * kern/ieee1275.c: ... to here. All users updated. Change all + parameter structs to use new type `grub_ieee1275_cell_t'. + * term/powerpc/ieee1275/ofconsole.c: Move ... + * term/ieee1275/ofconsole.c: ... to here. All users updated. + * disk/powerpc/ieee1275/ofdisk.c: Move ... + * disk/ieee1275/ofdisk.c: ... to here. All users updated. + * boot/powerpc/ieee1275/cmain.c: Change `grub_ieee1275_entry_fn' type + to return int. + * include/grub/i386/pc/console.h: Move to include/grub/console.h. + Remove unused prototypes. All users updated. + * include/grub/powerpc/ieee1275/console.h: Removed. + * include/grub/powerpc/ieee1275/ieee1275.h: Define + `grub_ieee1275_cell_t'. + * kern/powerpc/ieee1275/openfw.c: Include . + Cast comparisons with -1 to the correct type. + * loader/powerpc/ieee1275/linux.c (kernel_entry_t): Change parameter + type to match `grub_ieee1275_entry_fn'. + +2005-08-01 Yoshinori K. Okuji + + * DISTLIST: Added util/i386/pc/grub-probefs.c. + + * conf/i386-pc.rmk (sbin_UTILITIES): Added grub-probefs. + (grub_setup_SOURCES): Removed partmap/amiga.c, partmap/apple.c and + partmap/sun.c. + (grub_probefs_SOURCES): New variable. + + * util/i386/pc/grub-probefs.c: New file. + + * util/i386/pc/grub-setup.c (main): Call + grub_pc_partition_map_init, grub_ufs_init, grub_minix_init, + grub_hfs_init and grub_jfs_init to initialize the system. Call + grub_ufs_fini, grub_minix_fini, grub_hfs_fini, grub_jfs_init and + grub_pc_partition_map_fini to finish the system. + +2005-07-31 Yoshinori K. Okuji + + * loader/i386/pc/multiboot.c (grub_multiboot_is_elf32): New + function. + (grub_multiboot_load_elf32): Likewise. + (grub_multiboot_is_elf64): Likewise. + (grub_multiboot_load_elf64): Likewise. + (grub_multiboot_load_elf): Likewise. + (grub_rescue_cmd_multiboot): Call grub_multiboot_load_elf to load + an ELF32 or ELF64 file. + This is based on a patch from Ruslan Nikolaev . + + From Serbinenko Vladimir : + * kern/disk.c (grub_print_partinfo): Check if FS->LABEL is not + NULL before calling FS->LABEL. + * fs/fat.c (grub_fat_dir): Initialize DIRNAME to NULL. + * commands/ls.c (grub_ls_list_files): Show labels, if possible. + (grub_ls_list_disks): Check if FS and FS->LABEL are not NULL + before calling FS->LABEL. + +2005-07-26 Yoshinori K. Okuji + + * util/i386/pc/grub-install.in (datadir): New variable. + (libdir): Removed. + (pkgdatadir): New variable. + (pkglibdir): Removed. + +2005-07-24 Yoshinori K. Okuji + + * DISTLIST: Added util/i386/pc/grub-install.in. + + * util/i386/pc/grub-install.in: New file. + + * conf/i386-pc.rmk (sbin_SCRIPTS): New variable. + (grub_install_SOURCES): Likewise. + + * genmk.rb: Added support for scripts. + (Script): New class. + (scripts): New variable. + + * Makefile.in (install-local): Install sbin_SCRIPTS by + INSTALL_SCRIPT. + (uninstall): Remove sbin_SCRIPTS. + + * util/i386/pc/grub-setup.c (main): If the argument is not a GRUB + device, try to get a GRUB device by + grub_util_biosdisk_get_grub_dev. + Free DEST_DEV. + + * util/i386/pc/grub-mkdevicemap.c (usage): Remove a duplicated + description for --device-map. + +2005-07-20 Yoshinori K. Okuji + + Change the semantics of variable hooks. They now return strings + instead of error values. + + * util/i386/pc/grub-setup.c: Include grub/env.h. + (setup): Use grub_device_set_root instead of grub_env_set. + + * kern/rescue.c (grub_rescue_cmd_root): Use grub_env_set and + grub_env_get instead of grub_device_set_root and + grub_device_get_root, respectively. + + * kern/main.c (grub_env_write_root): New function. + (grub_set_root_dev): Register grub_env_write_hook for "root". Use + grub_env_set instead of grub_device_set_root. + + * kern/env.c (HASHSZ): Reduced to 13, because GRUB does not need + many variables. + (grub_env_set): Set ENV->VALUE to the result of ENV->WRITE_HOOK + rather than calling ENV->WRITE_HOOK afterwards. + (grub_env_get): Return the result of ENV->READ_HOOK rather than + passing a pointer of a pointer. + (grub_register_variable_hook): Change the types of "read_hook" and + "write_hook" to grub_env_read_hook_t and grub_env_write_hook_t, + respectively. + Allocate the default empty string on the heap, because this string + may be freed later. + + * kern/device.c: Include grub/env.h. + (grub_device_set_root): Removed. + (grub_device_get_root): Likewise. + (grub_device_open): Use grub_env_get instead of + grub_device_get_root. + + * include/grub/env.h (grub_env_read_hook_t): New type. + (grub_env_write_hook_t): Likewise. + (grub_env_var): Change the types of "read_hook" and "write_hook" + to grub_env_read_hook_t and grub_env_write_hook_t, respectively. + (grub_register_variable_hook): Likewise. + + * include/grub/device.h (grub_device_set_root): Removed. + (grub_device_set_root): Likewise. + + * fs/fat.c (grub_fat_dir): Make a copy of PATH in DIRNAME, and + make sure that DIRNAME terminates with '/', so that + grub_fat_find_dir will fail if PATH is not a directory. + + * commands/ls.c (grub_ls_list_files): Remove the qualifier const + from DIRNAME. + Use the qualifier auto for print_files and print_files_long. + If FS->DIR sets GRUB_ERRNO to GRUB_ERR_BAD_FILE_TYPE, try DIRNAME + as a regular file. + Put a newline only if there is no error. + (grub_cmd_ls): Remove grub_ls_print_files, because this is not + used. + +2005-07-20 Yoshinori K. Okuji + + * kern/partition.c (grub_partition_probe): Initialize PART to + NULL. Otherwise, when no partition map is registered, this returns + a garbage. + +2005-07-19 Yoshinori K. Okuji + + * partmap/apple.c (apple_partition_map_iterate): Check if POS + equals GRUB_DISK_SECTOR_SIZE to see if the partition table is + valid. + +2005-07-18 Yoshinori K. Okuji + + * commands/ls.c (grub_ls_list_disks): Print the filesystem + information on each device, if it does not have partitions. Print + "Device" instead of "Disk", because this function is not specific + to disk devices. + + * normal/main.c (grub_rescue_cmd_normal): Make the variable CONFIG + static to ensure that it is put on the memory rather than a + register. + +2005-07-17 Yoshinori Okuji + + * commands/cat.c (GRUB_MOD_INIT): Use better documentation. + (grub_cat_init): Likewise. + * loader/i386/pc/chainloader_normal.c (GRUB_MOD_INIT): Likewise. + (options): Likewise. + * commands/configfile.c (GRUB_MOD_INIT): Likewise. + (grub_configfile_init): Likewise. + * font/manager.c (GRUB_MOD_INIT): Likewise. + * commands/help.c (GRUB_MOD_INIT): Likewise. + (grub_help_init): Likewise. + * normal/command.c (grub_command_init): Likewise. + * loader/i386/pc/linux_normal.c (GRUB_MOD_INIT): Likewise. + * disk/loopback.c (grub_loop_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/ls.c (grub_ls_init): Likewise. + (GRUB_MOD_INIT): Likewise. + (options): Likewise. + * commands/boot.c (grub_boot_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/reboot.c (grub_reboot_init): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (grub_cmp_init): Likewise. + (GRUB_MOD_INIT): Likewise. + + * normal/arg.c: Use <> instead of "" to include header files. + (SHORT_ARG_HELP): New macro. + (SHORT_ARG_USAGE): Likewise. + (help_options): Specify SHORT_ARG_HELP and SHORT_ARG_USAGE instead + of 'h' and 'u' for help and usage, respectively. Use more GNU-like + descriptions. + (find_short): Check if C is 'h' or 'u' explicitly. + (grub_arg_show_help): Use space characters instead of tabs. Treat + SHORT_ARG_HELP and SHORT_ARG_USAGE exceptionally so that -h and -u + are shown with --help and --usage only if they are not used for + the command itself. + (parse_option): Use SHORT_ARG_HELP and SHORT_ARG_USAGE instead of + 'h' and 'u'. + + * include/grub/arg.h (struct grub_arg_option): Add the qualifier + const into "longarg". Change the type of "shortarg" to int. + +2005-07-17 Yoshinori Okuji + + * boot/i386/pc/boot.S (boot_drive_check): New label. + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_DRIVE_CHECK): New + macro. + + * util/i386/pc/grub-setup.c (setup): Added a workaround for BIOSes + which do not pass a boot drive correctly. Copied from GRUB Legacy. + +2005-07-17 Yoshinori Okuji + + * kern/i386/pc/startup.S (gate_a20_try_system_control_port_a): + When turning off Gate A20, skip the check and return immediately, + because this is not fatal usually. + +2005-07-17 Yoshinori Okuji + + * conf/i386-pc.rmk (pxeboot_img_LDFLAGS): The text address should + be 0x7C00 instead of 0x8000. + + * boot/i386/pc/pxeboot.S: Rewritten. + + * kern/i386/pc/startup.S (gate_a20_try_bios): No need to specify + EXT_C. + (gate_a20_check_state): Read a byte from 0x108000. Invert the + result. + +2005-07-16 Yoshinori K. Okuji + + * kern/i386/pc/startup.S (grub_gate_a20): Rewritten for + robustness. This routine now supports a BIOS call and System + Control Port A to modify the gate A20. + + * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): + Increased to 0x440. + +2005-07-12 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): dprintf the + device path and resulting ihandle. + (grub_ofdisk_close): dprintf the ihandle being closed. + (grub_ofdisk_read): dprintf function parameters. + * kern/mm.c (grub_mm_init_region): Likewise. + * loader/powerpc/ieee1275/linux.c: Remove extra whitespace. + (grub_linux_boot): dprintf the Linux entry point, initrd address and + size, and boot arguments. + (grub_rescue_cmd_linux): dprintf each ELF segment's address and size + before loading into memory. + (grub_rescue_cmd_initrd): dprintf the initrd's address and size + before loading into memory. + +2005-07-12 Yoshinori K. Okuji + + * kern/mm.c: Added much documentation. + (GRUB_MM_ALIGN_LOG2): When GRUB_CPU_SIZEOF_VOID_P is + 8, set to 5 instead of 8. + +2005-07-10 Yoshinori Okuji + + * DISTLIST: Added util/i386/pc/grub-mkimage.c. + + * conf/i386-pc.rmk (sbin_UTILITIES): Added grub-mkdevicemap. + (grub_mkdevicemap_SOURCES): New variable. + + * util/i386/pc/grub-mkdevicemap.c: New file. Mostly copied from + lib/device.c of GRUB Legacy. + +2005-07-10 Yoshinori Okuji + + * commands/ls.c (grub_ls_list_files): Check if *PATH is NUL + instead of PATH is NULL. + +2005-07-09 Vincent Pelletier + + * commands/cmp.c (BUFFER_SIZE): New macro. + (grub_cmd_cmp): Close the right file at the right time. Compare + only data just read. Don't report files of different size as + identical. Dynamically allocate buffers. Move variable + declarations at the beginning of function. + +2005-07-09 Yoshinori Okuji + + * aclocal.m4 (grub_I386_CHECK_REGPARM_BUG): The return value was + reverse. + +2004-07-04 Vincent Pelletier + + * normal/cmdline.c (grub_cmdline_get): Don't fallback on ctrl-d + when backspace is pressed at beginning of line. + +2005-07-03 Yoshinori Okuji + + * DISTLIST: Added genfslist.sh. + + * normal/main.c (fs_module_list): New variable. + (autoload_fs_module): New function. + (read_fs_list): Likewise. + (grub_normal_execute): Call read_fs_list. + + * kern/fs.c (grub_fs_autoload_hook): New variable. + (grub_fs_probe): Added support for auto-loading. + + * include/grub/normal.h (struct grub_fs_module_list): New struct. + (grub_fs_module_list_t): New type. + + * include/grub/fs.h (grub_fs_autoload_hook_t): New type. + (grub_fs_autoload_hook): New prototype. + + * genfslist.sh: New file. + + * genmk.rb: Added a rule to generate a filesystem list. + +2005-06-30 Marco Gerards + + * configure.ac: Fix the test for cross-compiling. + + * genmk.rb (Program): Use `$(CC)' instead of `$(BUILD_CC)'. Don't + define GRUB_UTIL anymore. + + * util/powerpc/ieee1275/grub-mkimage.c (load_note): Endian fixes + so this function works on other systems than just big endian. + (load_modules): Likewise. + (add_segments): Likewise. + +2005-06-23 Hollis Blanchard + + * kern/misc.c (grub_vsprintf): Add `longfmt'. If format string + contains `l' modifier, get a long from va_arg(). + +2005-06-23 Yoshinori K. Okuji + + * kern/mm.c (grub_free): If the next free block which is being + merged is the first free block, set the first block to the block + being freed. + Reported by Vincent Guffens . + +2005-05-08 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Initialize + `grub_ieee1275_chosen'. + +2005-05-08 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (module_info): Remove definition. + (grub_ieee1275_chosen): New variable. + (cmain): Initialize and use `grub_ieee1275_chosen' instead of + `chosen'. + * boot/powerpc/ieee1275/crt0.S (init_stack): Remove stack space. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Rename first argument to `phandle' for consistency. + (grub_ieee1275_get_property_length): Likewise. + (grub_ieee1275_next_property): Likewise. Change type of first argument + to grub_ieee1275_phandle_t. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_entry_fn): + Move export next to declaration. + (grub_ieee1275_chosen): New variable. + * include/grub/powerpc/ieee1275/kernel.h (GRUB_IEEE1275_MODULE_BASE): + Correct cosmetic typo. + * kern/powerpc/ieee1275/init.c (grub_set_prefix): Use + `grub_ieee1275_chosen'. + * kern/powerpc/ieee1275/openfw.c (grub_map): Likewise. + * loader/powerpc/ieee1275/linux.c (grub_linux_boot): Likewise. + (grub_rescue_cmd_linux): Set `initrd_addr' to 0. + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_refresh): Use + `grub_ieee1275_chosen'. + +2005-05-10 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Remove code to parse + /chosen/bootargs. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Parse + /chosen/bootargs as "variable=value" pairs. + +2005-05-08 Vincent Pelletier + + * include/grub/misc.h (grub_dprintf): New macro. + (grub_real_dprintf): New prototype. + (grub_strword): Likewise. + (grub_iswordseparator): Likewise. + * kern/misc.c (grub_real_dprintf): New function. + (grub_strword): Likewise. + (grub_iswordseparator): Likewise. + +2005-04-30 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c: Don't include grub/machine/init.h. + (roundup): Remove macro. + (grub_ieee1275_flags): Make static. + (grub_ieee1275_realmode): Remove. + (grub_ieee1275_test_flag): New function. + (grub_ieee1275_set_flag): Likewise. + (find_options): Rename to `grub_ieee1275_find_options'; update + callers. Set GRUB_IEEE1275_FLAG_REAL_MODE and + GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS. + (cmain): New prototype. + (cmain): Use `grub_ieee1275_set_flag' instead of accessing + `grub_ieee1275_flags' directly. + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Remove + machine/biosdisk.h. + * disk/powerpc/ieee1275/ofdisk.c: Include grub/machine/ofdisk.h. + Don't include grub/machine/init.h. + (grub_ofdisk_open): Call `grub_ieee1275_test_flag'. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags): + Remove prototype. + (grub_ieee1275_realmode): Likewise. + (grub_ieee1275_flag): New enum. + (grub_ieee1275_test_flag): New prototype. + (grub_ieee1275_set_flag): New prototype. + * include/grub/powerpc/ieee1275/init.h: Remove file. + * include/grub/powerpc/ieee1275/ofdisk.h: New file. + * kern/powerpc/ieee1275/init.c: Don't include grub/machine/init.h. + Include grub/machine/console.h. Include grub/machine/ofdisk.h. + (grub_machine_fini): Don't call `grub_ieee1275_release'. Remove + comment. + * kern/powerpc/ieee1275/openfw.c (grub_claimmap): Call + `grub_ieee1275_test_flag'. + (grub_ieee1275_encode_devname): Likewise. + +2005-04-21 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_encode_devname): New prototype. + (grub_ieee1275_get_filename): Likewise. + * kern/powerpc/ieee1275/init.c (grub_translate_ieee175_path): New + function. + (grub_set_prefix): Likewise. + (grub_machine_init): Call grub_set_prefix. + * kern/powerpc/ieee1275/openfw.c: Fix typos. + (grub_parse_type): New enum. + (grub_ieee1275_get_devargs): New function. + (grub_ieee1275_get_devname): Likewise. + (grub_ieee1275_parse_args): Likewise. + (grub_ieee1275_get_filename): Likewise. + (grub_ieee1275_encode_devname): Likewise. + +2005-03-30 Marco Gerards + + * kern/powerpc/ieee1275/init.c (grub_machine_fini): Don't call + `grub_loader_unset'. + +2005-03-26 Hollis Blanchard + + * commands/ieee1275/halt.c (grub_cmd_halt): Call grub_halt + instead of grub_ieee1275_interpret. + (grub_halt_init): New function. + (grub_halt_fini): Likewise. + (GRUB_MOD_INIT): Correct message grammar. + * commands/ieee1275/reboot.c (grub_cmd_reboot): Call grub_reboot + instead of grub_ieee1275_interpret. + (grub_reboot_init): New function. + (grub_reboot_fini): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace + commands/i386/pc/halt.c, commands/i386/pc/reboot.c, and + util/i386/pc/misc.c with commands/ieee1275/halt.c, + commands/ieee1275/reboot.c, and util/powerpc/ieee1275/misc.c. + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_fini): New + function. + * include/grub/powerpc/ieee1275/console.h (grub_console_fini): + Add prototype. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_reboot): Add + prototype. + (grub_halt): Likewise. + * include/grub/powerpc/ieee1275/init.h: Remove inaccurate comment. + (cmain): Remove __attribute__((unused)). + * kern/powerpc/ieee1275/init.c (grub_heap_start): New variable. + (grub_heap_len): Likewise. + (grub_machine_fini): New function. + * kern/powerpc/ieee1275/openfw.c (grub_reboot): New function. + (grub_halt): Likewise. + * term/powerpc/ieee1275/ofconsole.c (grub_console_fini): New + function. + * util/powerpc/ieee1275/misc.c: New file. + +2005-03-19 Yoshinori K. Okuji + + * DISTLIST: New file. + * gendistlist.sh: Likewise. + + * Makefile.in (COMMON_DISTFILES): Removed. + (BOOT_DISTFILES): Likewise. + (CONF_DISTFILES): Likewise. + (DISK_DISTFILES): Likewise. + (FS_DISTFILES): Likewise. + (INCLUDE_DISTFILES): Likewise. + (KERN_DISTFILES): Likewise. + (LOADER_DISTFILES): Likewise. + (TERM_DISTFILES): Likewise. + (UTIL_DISTFILES): Likewise. + (DISTFILES): Likewise. + (uninstall): Uninstall files in $(pkgdata_DATA). + (DISTLIST): New target. + (distdir): Use the contents of the file DISTLIST to get a list of + distributed files. + +2005-03-18 Yoshinori K. Okuji + + * fs/fat.c (grub_fat_mount): Ignore the 3rd bit of a media + descriptor. This is ported from GRUB Legacy. + + * gencmdlist.sh: Added an extra semicolon to make it work with + old sed versions. Reported by Robert Bihlmeyer + . + +2005-03-08 Yoshinori Okuji + + Automatic loading of commands is supported. + + * normal/main.c (read_command_list): New function. + (grub_normal_execute): Call read_command_list. + + * normal/command.c (grub_register_command): Return zero or CMD. + Allocate CMD->NAME from the heap. + Initialize CMD->MODULE_NAME to zero. + Find the same name as well. If the same command is found and it is + a dummy command, overwrite members. If it is not a dummy command, + return zero. + (grub_unregister_command): Free Q->NAME and Q->MODULE_NAME. + (grub_command_find): If a dummy command is found, load a module + and retry to find a command only once. + + * normal/cmdline.c (grub_tab_complete): Call grub_command_find to + make sure that each command is loaded. + + * include/grub/normal.h (GRUB_COMMAND_FLAG_NOT_LOADED): New + macro. + (struct grub_command): Remove const from the member `name'. + Add a new member `module_name'. + (grub_register_command): Return grub_command_t. + + * commands/help.c (grub_cmd_help): Call grub_command_find to make + sure that each command is loaded. + + * genmk.rb (PModule::rule): Specify a module name without the + suffix ".mod" to gencmdlist.sh. + +2005-03-02 Yoshinori K. Okuji + + * gencmdlist.sh: New file. + + * genmk.rb (PModule::rule): Generate a rule for a command list. + Clean command.lst. + Generate command.lst from $(COMMANDFILES). + + * Makefile.in (COMMON_DISTFILES): Added gencmdlist.sh. + (DATA): Added $(pkgdata_DATA). + (install-local): Install files in $(pkgdata_DATA). + +2005-03-02 Yoshinori K. Okuji + + * term/i386/pc/vga.c (debug_command): Removed. + (GRUB_MOD_INIT): Do not register the command "debug". + + From Hollis Blanchard: + * commands/configfile.c: New file. + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + commands/configfile.c. + (pkgdata_MODULES): Added configfile.mod. + (configfile_mod_SOURCES): New variable. + (configfile_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added + commands/configfile.c. + (pkgdata_MODULES): Added configfile.mod. + (configfile_mod_SOURCES): New variable. + (configfile_mod_CFLAGS): Likewise. + * util/grub-emu.c (main): Call grub_configfile_init and + grub_configfile_fini. + * include/grub/normal.h [GRUB_UTIL] (grub_configfile_init): New + prototype. + [GRUB_UTIL] (grub_configfile_fini): Likewise. + +2005-02-27 Yoshinori K. Okuji + + * normal/arg.c (grub_arg_show_help): Do not show the bug report + address. + + * commands/help.c (grub_cmd_help): Do not print newlines after + the last command in print_command_help. + +2005-02-27 Yoshinori K. Okuji + + * commands/default.h: New file. + * commands/timeout.h: Likewise. + * normal/context.c: Likewise. + + * util/misc.c: Do not include sys/times.h. + Include sys/time.h and grub/machine/time.h. + (grub_get_rtc): Rewritten with gettimeofday. + + * util/grub-emu.c (main): Call grub_default_init and + grub_timeout_init before grub_normal_init, and call + grub_timeout_fini and grub_default_fini after grub_main. + + * util/console.c (grub_ncurses_checkkey): Return the read + character or -1. + + * normal/menu.c (run_menu): Set MENU->TIMEOUT to -1 once it + timeouts. + + * normal/main.c (read_config_file): Push MENU. If this fails, + print an error and wait for a user input. + Print an error only if GRUB_ERRNO is not GRUB_ERR_NONE. + If a menu is empty or an error occurs, pop MENU. + (grub_normal_execute): Pop and free MENU after grub_menu_run + returns. + + * kern/loader.c (grub_loader_boot): Call grub_machine_fini. + + * include/grub/powerpc/ieee1275/time.h [GRUB_UTIL]: Do not + include time.h. + [GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as + without GRUB_UTIL. + * include/grub/i386/pc/time.h [GRUB_UTIL]: Do not include + time.h. + [GRUB_UTIL] (GRUB_TICKS_PER_SECOND): Use the same definition as + without GRUB_UTIL. + + * include/grub/normal.h (struct grub_menu_list): New struct. + (grub_menu_list_t): New type. + (struct grub_context): New struct. + (grub_context_t): New type. + (grub_register_command): Got rid of EXPORT_FUNC. + (grub_unregister_command): Likewise. + (grub_context_get): New prototype. + (grub_context_get_current_menu): Likewise. + (grub_context_push_menu): Likewise. + (grub_context_pop_menu): Likewise. + [GRUB_UTIL] (grub_default_init): Likewise. + [GRUB_UTIL] (grub_default_fini): Likewise. + [GRUB_UTIL] (grub_timeout_init): Likewise. + [GRUB_UTIL] (grub_timeout_fini): Likewise. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added commands/default.c, + commands/timeout.c and normal/context.c. + (pkgdata_MODULES): Added default.mod and timeout.mod. + (normal_mod_SOURCES): Added normal/context.c. + (default_mod_SOURCES): New variable. + (default_mod_CFLAGS): Likewise. + (timeout_mod_SOURCES): Likewise. + (timeout_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Copied from + conf/i386-pc.rmk. + (pkgdata_MODULES): Added default.mod and timeout.mod. + (normal_mod_SOURCES): Added normal/context.c. + (default_mod_SOURCES): New variable. + (default_mod_CFLAGS): Likewise. + (timeout_mod_SOURCES): Likewise. + (timeout_mod_CFLAGS): Likewise. + + * Makefile.in (all-local): Added $(MKFILES). + +2005-02-21 Vincent Pelletier + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add `partmap/sun.c'. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `sun.mod'. + (sun_mod_SOURCES, sun_mod_CFLAGS): New variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `partmap/sun.c'. + (pkgdata_MODULES): Add `sun.mod'. + (sun_mod_SOURCES, sun_mod_CFLAGS): New variables. + * include/grub/partition.h (grub_sun_partition_map_init): New + prototype. + (grub_sun_partition_map_fini): Likewise. + * partmap/sun.c: New file. + * util/grub-emu.c (main): Initialize and de-initialize the sun + partitionmap support. + +2005-02-19 Yoshinori K. Okuji + + This implements an Emacs-like menu entry editor. + + * normal/menu_entry.c: New file. + + * util/console.c (grub_ncurses_putchar): Translate some Unicode + characters to ASCII. + (saved_char): New variable. + (grub_ncurses_checkkey): Rewritten completely. + (grub_ncurses_getkey): Likewise. + (grub_ncurses_init): Call raw instead of cbreak. + + * normal/menu.c (print_entry): Do not put a space. + (init_page): Renamed to ... + (grub_menu_init_page): ... this. All callers changed. + (edit_menu_entry): Removed. + (run_menu): Call grub_menu_entry_run instead of edit_menu_entry. + + * normal/cmdline.c (grub_cmdline_run): Call grub_setcursor. + + * kern/misc.c (grub_vprintf): Call grub_refresh. + + * normal/menu.c (DISP_LEFT): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LEFT): ... this. + * normal/menu.c (DISP_UP): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UP): ... this. + * normal/menu.c (DISP_RIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_RIGHT): ... this. + * normal/menu.c (DISP_DOWN): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_DOWN): ... this. + * normal/menu.c (DISP_HLINE): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_HLINE): ... this. + * normal/menu.c (DISP_VLINE): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_VLINE): ... this. + * normal/menu.c (DISP_UL): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UL): ... this. + * normal/menu.c (DISP_UR): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_UR): ... this. + * normal/menu.c (DISP_LL): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LL): ... this. + * normal/menu.c (DISP_LR): Renamed to ... + * include/grub/term.h (GRUB_TERM_DISP_LR): ... this. + * normal/menu.c (TERM_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_WIDTH): ... this. + * normal/menu.c (TERM_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_HEIGHT): ... this. + * normal/menu.c (TERM_INFO_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_INFO_HEIGHT): ... this. + * normal/menu.c (TERM_MARGIN): Renamed to ... + * include/grub/term.h (GRUB_TERM_MARGIN): ... this. + * normal/menu.c (TERM_SCROLL_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_SCROLL_WIDTH): ... this. + * normal/menu.c (TERM_TOP_BORDER_Y): Renamed to ... + * include/grub/term.h (GRUB_TERM_TOP_BORDER_Y): ... this. + * normal/menu.c (TERM_LEFT_BORDER_X): Renamed to ... + * include/grub/term.h (GRUB_TERM_LEFT_BORDER_X): ... this. + * normal/menu.c (TERM_BORDER_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_BORDER_WIDTH): ... this. + * normal/menu.c (TERM_MESSAGE_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): ... this. + * normal/menu.c (TERM_BORDER_HEIGHT): Renamed to ... + * include/grub/term.h (GRUB_TERM_BORDER_HEIGHT): ... this. + * normal/menu.c (TERM_NUM_ENTRIES): Renamed to ... + * include/grub/term.h (GRUB_TERM_NUM_ENTRIES): ... this. + * normal/menu.c (TERM_FIRST_ENTRY_Y): Renamed to ... + * include/grub/term.h (GRUB_TERM_FIRST_ENTRY_Y): ... this. + * normal/menu.c (TERM_ENTRY_WIDTH): Renamed to ... + * include/grub/term.h (GRUB_TERM_ENTRY_WIDTH): ... this. + * normal/menu.c (TERM_CURSOR_X): Renamed to ... + * include/grub/term.h (GRUB_TERM_CURSOR_X): ... this. + All callers changed. + + * include/grub/normal.h: New prototype. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + normal/menu_entry.c. + (normal_mod_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + (normal_mod_SOURCES): Likewise. + +2005-02-15 Yoshinori K. Okuji + + * include/grub/normal.h (grub_halt_init): New prototype. + (grub_halt_fini): Likewise. + (grub_reboot_init): Likewise. + (grub_reboot_fini): Likewise. + + * util/grub-emu.c: Include signal.h. + (main_env): New global variable. + (grub_machine_init): Ignore SIGINT. Otherwise grub-emu cannot + catch C-c. + (grub_machine_fini): New function. + (main): Call grub_halt_init and grub_reboot_init before + grub_main, and grub_reboot_fini and grub_halt_fini after it. + Call setjmp with MAIN_ENV to go back afterwards. + Call grub_machine_fini right before return. + + * include/grub/util/misc.h: Include setjmp.h. + (main_env): New prototype. + + * include/grub/kernel.h (grub_machine_fini): New prototype. + * include/grub/i386/pc/biosdisk.h (grub_biosdisk_fini): Likewise. + * include/grub/i386/pc/console.h (grub_console_fini): Likewise. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_fini): New function. + * kern/i386/pc/init.c (grub_machine_fini): Likewise. + * term/i386/pc/console.c (grub_console_fini): Likewise. + + * util/i386/pc/misc.c: New file. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Added + util/i386/pc/misc.c, commands/i386/pc/halt.c and + commands/i386/pc/reboot.c. + +2005-02-14 Guillem Jover + + * include/grub/dl.h (grub_dl_check_header): New prototype. + (grub_arch_dl_check_header): Change return type to grub_err_t, + remove size parameter and export function. Update all callers. + * kern/dl.c (grub_dl_check_header): New function. + (grub_dl_load_core): Use `grub_dl_check_header' instead of + `grub_arch_dl_check_header'. Check ELF type. Check if sections + are inside the core. + * kern/i386/dl.c (grub_arch_dl_check_header): Remove arch + independent ELF header checks. + * kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise. + * loader/i386/pc/multiboot.c (grub_rescue_cmd_multiboot): Use + `grub_dl_check_header' instead of explicit checks. Check for the + ELF type. + * loader/powerpc/ieee1275/linux.c (grub_rescue_cmd_linux): Use + `grub_dl_check_header' instead of explicit checks. Remove arch + specific ELF header checks. + + * util/grub-emu.c (grub_arch_dl_check_header): Remove the + argument SIZE. + +2005-02-13 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add ls.mod. + * include/grub/powerpc/libgcc.h (__mulsf3): New prototype. + +2005-02-12 Hollis Blanchard + + * kern/partition.c (grub_partition_probe): Clear `grub_errno' and + return 0 if `grub_errno' is GRUB_ERR_BAD_PART_TABLE. + (part_map_iterate): Clear `grub_errno' and return 0 if + `partmap->iterate' returns GRUB_ERR_BAD_PART_TABLE. + * partmap/amiga.c (amiga_partition_map_iterate): Return + GRUB_ERR_BAD_PART_TABLE if no partition map magic is found. + * partmap/apple.c (apple_partition_map_iterate): Likewise. + +2005-02-01 Guillem Jover + + * loader/i386/pc/multiboot_normal.c (GRUB_MOD_INIT): Fix module + help info. + +2005-01-31 Marco Gerards + + * include/grub/powerpc/ieee1275/loader.h (grub_load_linux): + Removed prototype. + (grub_rescue_cmd_linux): New prototype. + (grub_rescue_cmd_initrd): Likewise. + * powerpc/ieee1275/linux.c (grub_linux_boot): Remove struct + `bi_rec'. + (grub_linux_release_mem): Release the memory for the initrd. + (grub_load_linux): Renamed from this... + (grub_rescue_cmd_linux): ...To this. Changed all callers. + Changed `entry' not to be static. Loop over memory regions to + find another one when the default fails. + (grub_rescue_cmd_initrd): New function. + (grub_linux_init): Remove function. + (grub_linux_fini): Likewise. + (GRUB_MOD_INIT): Register `initrd'. + (GRUB_MOD_FINI): Unregister `initrd'. + * powerpc/ieee1275/linux_normal.c (grub_linux_normal_init): + Function removed. + (grub_linux_normal_fini): Likewise. + (GRUB_MOD_INIT): Register `initrd'. + (GRUB_MOD_FINI): Unregister `initrd'. + +2005-01-31 Marco Gerards + + * commands/help.c: New file. + * normal/arg.c (show_help): Renamed to... + (grub_arg_show_help): ... this. + * commands/i386/pc/halt.c: New file. + * commands/i386/pc/reboot.c: Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `commands/help.c'. + (pkgdata_MODULES): Add `reboot.mod', `halt.mod' and `help.mod'. + (help_mod_SOURCES, help_mod_CFLAGS, reboot_mod_SOURCES) + (reboot_mod_CFLAGS, halt_mod_SOURCES, halt_mod_CFLAGS): New + variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `commands/help.c'. + (pkgdata_MODULES): Add `help.mod'. + (help_mod_SOURCES, help_mod_CFLAGS): New variables. + * grub/i386/pc/init.h (grub_reboot): New prototype. + (grub_halt): Likewise. + * include/grub/normal.h (grub_arg_show_help): New prototype. + (grub_help_init): Likewise. + (grub_help_fini): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize the help + command. + + * normal/cmdline.c (grub_cmdline_get): Doc fix. + + * normal/command.c (grub_command_init): Fixed the description of + the `set' and `unset' commands. + +2005-01-31 Marco Gerards + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_interpret): New + function. + * commands/ieee1275/halt.c: New file. + * commands/ieee1275/reboot.c: Likewise. + * commands/ieee1275/suspend.c (grub_cmd_suspend): Use + `__attribute__ ((unused))'. Some GCS related fixed. + (grub_suspend_init) [GRUB_UTIL]: Function removed. + (grub_suspend_fini): Likewise. + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add `reboot.mod' + and `halt.mod'. + (reboot_mod_SOURCES, reboot_mod_CFLAGS, halt_mod_SOURCES) + (halt_mod_CFLAGS): New variables. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_interpret): New prototype. + +2005-01-29 Yoshinori K. Okuji + + * include/grub/misc.h (memmove): New prototype. + (memcpy): Likewise. + +2005-01-22 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Don't initialize + `devpath' to 0. Use `name' instead of `devpath' with `grub_strndup'. + +2005-01-22 Marco Gerards + + * kern/misc.c (grub_strndup): Function rewritten. + +2005-01-22 Vincent Pelletier + + * normal/menu.c (TERM_WIDTH): Macro redefined. + (TERM_TOP_BORDER_Y): Likewise. + (draw_border): Replaced while-loop by a for-loop. Make the number + of lines consistent with the number of lines displayed in + print_entries. Added a margin below the rectangle. + (print_entry): Make the entry fit in the rectangle. + (print_entries): Display the scroll arrows next to the right + border. + +2005-01-21 Marco Gerards + + * fs/minix.c (grub_minix_find_file): Reserve more space for + `fpath' so the \0 can be stored. Use `grub_strcpy' instead of + `grub_strncpy' to copy `path' into it. + +2005-01-21 Marco Gerards + + Add the loopback device, a device via which files can be accessed + as devices. + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add `disk/loopback.c'. + (pkgdata_MODULES): Add loopback.mod. + (loopback_mod_SOURCES): New variable. + (loopback_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add + `disk/loopback.c'. + (pkgdata_MODULES): Add loopback.mod. + (loopback_mod_SOURCES): New variable. + (loopback_mod_CFLAGS): Likewise. + * disk/loopback.c: new file. + * include/grub/normal.h (grub_loop_init): New prototype. + (grub_loop_fini): New prototype. + * util/grub-emu.c (main): Initialize and de-initialize loopback + support. + * include/grub/disk.h (grub_disk_dev_id): Add + `GRUB_DISK_DEVICE_LOOPBACK_ID'. + +2005-01-20 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_enter): New + function. + * conf/powerpc-ieee1275.rmk (pkgdata_MODULES): Add suspend.mod. + (suspend_mod_SOURCES): New variable. + (suspend_mod_CFLAGS): Likewise. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_enter): + New prototype. + * commands/ieee1275/suspend.c: New file. + +2005-01-20 Timothy Baldwin + + * include/grub/dl.h (GRUB_MOD_INIT): Changed `__attribute__ + ((unused))' to `__attribute__ ((used))'. + (GRUB_MOD_FINI): Likewise. + * kern/dl.c (grub_dl_load_file): Fix null pointer dereference. + * genmk.rb (PModule): Assign space to common symbols when linking + modules. + +2005-01-20 Marco Gerards + + * include/grub/mm.h (grub_mm_init_region): Change the type of the + `unsigned' arguments to `grub_size_t'. + (grub_malloc): Likewise. + (grub_realloc): Likewise. + (grub_memalign): Likewise. + * kern/i386/dl.c (grub_arch_dl_check_header): Likewise. + * kern/powerpc/dl.c (grub_arch_dl_check_header): Likewise. + * util/misc.c (grub_malloc): Likewise. + (grub_realloc): Likewise. + * kern/mm.c (get_header_from_pointer): Change the casts to + `unsigned' into a cast to `grub_size_t'. + + * fs/fshelp.c (grub_fshelp_find_file): The `oldnode' should always + point to `currnode' when `currnode' is changed. + + * util/grub-emu.c (main): Initialize `progname'. Reported by Nico + Schottelius . + +2005-01-09 Hollis Blanchard + + * util/powerpc/ieee1275/grub-mkimage.c: Include . + (note_path): Remove variable. + (GRUB_IEEE1275_NOTE_NAME): New macro. + (GRUB_IEEE1275_NOTE_TYPE): Likewise. + (grub_ieee1275_note_hdr): New structure. + (grub_ieee1275_note_desc): Likewise. + (grub_ieee1275_note): Likewise. + (load_note): Remove `dir' argument. All callers updated. Remove + `note_img' and `path'. Do not load a file from `note_path'. + Initialize a struct grub_ieee1275_note and write that to `out'. + Use GRUB_IEEE1275_MODULE_BASE instead of MODULE_BASE. + +2005-01-05 Marco Gerards + + * util/misc.c (grub_util_read_image): Revert last change. It + called `grub_util_read_at', which seeks from the beginning of the + file. + +2005-01-04 Hollis Blanchard + + * TODO: Add note about endianness in grub-mkimage. + * boot/powerpc/ieee1275/crt0.S (note): Remove unused .note + section. + * conf/powerpc-ieee1275.rmk (bin_UTILITIES): Add grub-mkimage. + (grub_mkimage_SOURCES): New target. + * include/grub/kernel.h (grub_start_addr): Remove variable. + (grub_end_addr): Likewise. + (grub_total_module_size): Likewise. + (grub_kernel_image_size): Likewise. + (GRUB_MODULE_MAGIC): New constant. + (grub_module_info): New structure. + (grub_arch_modules_addr): New prototype. + (grub_get_end_addr): Remove prototype. + * include/grub/i386/pc/kernel.h (grub_end_addr): New prototype. + * include/grub/powerpc/ieee1275/kernel.h: New file. + * include/grub/util/misc.h (grub_util_get_fp_size): New + prototype. + (grub_util_read_at): Likewise. + (grub_util_write_image_at): Likewise. + * kern/main.c (grub_get_end_addr): Remove function. + (grub_load_modules): Call grub_arch_modules_addr instead of using + grub_end_addr. Look for a grub_module_info struct in memory. Use + the grub_module_info fields instead of calling grub_get_end_addr + as loop conditions. Move grub_add_unused_region code here. + (grub_add_unused_region): Remove function. + * kern/i386/pc/init.c: Include grub/cache.h. + (grub_machine_init): Remove call to grub_get_end_addr. Remove + one call to add_mem_region. + (grub_arch_modules_addr): New function. + * kern/powerpc/ieee1275/init.c (grub_end_addr): Remove variable. + (grub_total_module_size): Likewise. + Include grub/machine/kernel.h. + (grub_arch_modules_addr): New function. + * util/grub-emu.c (grub_end_addr): Remove variable. + (grub_total_module_size): Likewise. + (grub_arch_modules_addr): New function. + * util/misc.c: Include unistd.h. + (grub_util_get_fp_size): New function. + (grub_util_read_at): Likewise. + (grub_util_write_image_at): Likewise. + (grub_util_read_image): Call grub_util_read_at. + (grub_util_write_image): Call grub_util_write_image_at. + * util/i386/pc/grub-mkimage.c (generate_image): Allocate + additional memory in kernel_img for a struct grub_module_info. + Fill in that grub_module_info. + * util/powerpc/ieee1275/grub-mkimage.c: New file. + +2005-01-03 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_milliseconds): + New function. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_milliseconds): New prototype. + * include/grub/powerpc/ieee1275/time.h (GRUB_TICKS_PER_SECOND): + Change to 1000. + * kern/powerpc/ieee1275/init.c (grub_get_rtc): Call + grub_ieee1275_milliseconds. + +2005-01-03 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (grub_ieee1275_realmode): New + variable. + (find_options): New function. + (cmain): Call find_options. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_realmode): New extern variable. + * kern/powerpc/ieee1275/openfw.c (grub_claimmap): Only call + grub_map if grub_ieee1275_realmode is false. + +2004-12-29 Marco Gerards + + * normal/cmdline.c (grub_cmdline_get): Redone logic so no empty + lines are inserted and make it work like readline. Reported by + Vincent Pelletier . + +2004-12-28 Marco Gerards + + * boot/powerpc/ieee1275/crt0.S (_start): Don't set up the stack. + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCE): Remove + `kern/powerpc/cache.S'. + +2004-12-27 Marco Gerards + + * genmk.rb: Handle the `Program' class in the main loop. Written + by Johan Rydberg . + (Program): New class. + (programs): New variable. + * boot/powerpc/ieee1275/cmain.c: Include + instead of "grub/machine/ieee1275.h". Include + instead of "grub/kernel.h". Include . + (help_arch): Function removed. + * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add + `powerpc/libgcc.h' and `loader.h'. + (pkgdata_PROGRAMS): New variable. + (sbin_UTILITIES): Variable removed. + (grub_emu_SOURCES): Added kern/powerpc/cache.S. + (grubof_SOURCES): Variable re-defined so it only includes the + core functionality. + (grubof_CFLAGS): Remove `-DGRUBOF'. + (pkgdata_MODULES, fshelp_mod_SOURCES, fshelp_mod_CFLAGS, + (fat_mod_SOURCES, fat_mod_CFLAGS, ext2_mod_SOURCES) + (ext2_mod_CFLAGS, ufs_mod_SOURCES, ufs_mod_CFLAGS) + (minix_mod_SOURCES, minix_mod_CFLAGS, hfs_mod_SOURCES) + (hfs_mod_CFLAGS, jfs_mod_SOURCES, jfs_mod_CFLAGS) + (iso9660_mod_SOURCES, iso9660_mod_CFLAGS, _linux_mod_SOURCES) + (_linux_mod_CFLAGS, linux_mod_SOURCES, linux_mod_CFLAGS) + (normal_mod_SOURCES, normal_mod_CFLAGS, normal_mod_ASFLAGS) + (hello_mod_SOURCES, hello_mod_CFLAGS, boot_mod_SOURCES) + (boot_mod_CFLAGS, terminal_mod_SOURCES, terminal_mod_CFLAGS) + (ls_mod_SOURCES, ls_mod_CFLAGS, cmp_mod_SOURCES, cmp_mod_CFLAGS) + (cat_mod_SOURCES, cat_mod_CFLAGS, font_mod_SOURCES) + (font_mod_CFLAGS, amiga_mod_SOURCES, amiga_mod_CFLAGS) + (apple_mod_SOURCES, apple_mod_CFLAGS, pc_mod_SOURCES) + (pc_mod_CFLAGS): New variables. + * disk/powerpc/ieee1275/ofdisk.c: Include . + (grub_ofdisk_iterate): Add a prototype for `dev_iterate'. + * include/grub/dl.h (grub_arch_dl_sync_caches): New prototype. + * include/grub/loader.h (grub_os_area_addr, grub_os_area_size): + Moved from here... + * include/grub/i386/pc/init.h (grub_os_area_addr) + (rub_os_area_size): ... to here. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_entry_fn): Export symbol. + * include/grub/powerpc/ieee1275/init.h: New file. + * include/grub/powerpc/libgcc.h: Likewise. + * include/grub/cache.h: Likewise. + * kern/powerpc/cache.S: Likewise. Written by Hollis Blanchard + . + * kern/dl.c: Include . + (grub_dl_flush_cache): New function. + (grub_dl_load_core): Call `grub_dl_flush_cache' to flush the cache + for this module. + * kern/powerpc/ieee1275/init.c (grub_ofdisk_init) + (grub_console_init): Removed prototypes. + (grub_machine_init): Don't initialize the modules anymore. + * kern/powerpc/ieee1275/openfw.c (grub_map): Make the function + static. + * include/grub/powerpc/types.h (GRUB_HOST_WORDS_LITTLEENDIAN): + Macro undef removed. + (GRUB_HOST_WORDS_BIGENDIAN): New macro. + * kern/powerpc/dl.c (grub_arch_dl_relocate_symbols): Add + relocation `R_PPC_REL32'. Return an error when the relocation is + unknown. + * Makefile.in (DATA): Add `$(pkgdata_PROGRAMS)'. + * kern/i386/pc/init.c (grub_arch_sync_caches): New function. + * util/misc.c (grub_arch_sync_caches): Likewise. + +2004-12-19 Marco Gerards + + * conf/powerpc-ieee1275.rmk (MOSTLYCLEANFILES): Remove + `symlist.c', add `grubof_symlist.c'. + (symlist.c): Variable removed. + (grubof_HEADERS): Variable added. + (grubof_symlist.c): New target. + (kernel_syms.lst): Use `grubof_HEADERS' instead of + `kernel_img_HEADERS'. + (grubof_SOURCES): Add `kern/powerpc/dl.c' and `grubof_symlist.c'. + * kern/powerpc/dl.c: New file. + * kern/powerpc/ieee1275/init.c (grub_arch_dl_check_header): + Function removed. + (grub_arch_dl_relocate_symbols): Likewise. + (grub_register_exported_symbols): Likewise. + +2004-12-13 Marco Gerards + + * fs/ext2.c (grub_ext2_open): Don't use data after freeing it. + (grub_ext2_dir): Likewise. Don't return in case of an error, jump + to fail instead. Reported by Vincent Pelletier + . + + * fs/fshelp.c (grub_fshelp_find_file): Don't free `oldnode' when + it is not allocated. Reported by Vincent Pelletier + . + + * normal/cmdline.c (grub_tab_complete): Add a blank line to the + output so the output looks better. + +2004-12-04 Marco Gerards + + Modulize the partition map support and add support for the amiga + partition map. + + * commands/ls.c: Include instead of + . + * kern/disk.c: Likewise. + * kern/rescue.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * normal/cmdline.c: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + (grub_machine_init): Call `grub_pc_partition_map_init', + `grub_amiga_partition_map_init' and + `grub_apple_partition_map_init'. + * conf/i386-pc.rmk (kernel_img_SOURCES): Remove + `disk/i386/pc/partition.c'. Add `kern/partition.c'. + (kernel_img_HEADERS): Remove `machine/partition.h'. Add + `partition.h' and `pc_partition.h'. + (grub_setup_SOURCES): Remove + `disk/i386/pc/partition.c'. Add `kern/partition.c', + `partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add `amiga.mod', `apple.mod' and `pc.mod'. + (amiga_mod_SOURCES, amiga_mod_CFLAGS, apple_mod_SOURCES) + (apple_mod_CFLAGS, pc_mod_SOURCES, pc_mod_CFLAGS): New variables. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove + `disk/powerpc/ieee1275/partition.c'. Add `kern/partition.c', + `partmap/amiga.c', `partmap/apple.c' and `partmap/pc.c'. + (grubof_SOURCES): Likewise. + * disk/i386/pc/partition.c: File removed. + * disk/powerpc/ieee1275/partition.c: Likewise. + * include/grub/powerpc/ieee1275/partition.h: Likewise. + * include/grub/i386/pc/partition.h: Likewise. + * kern/partition.c: New file. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/pc.c: Likewise. + * include/grub/partition.h: Likewise.. + * include/grub/pc_partition.h: Likewise. + * util/grub-emu.c: Include instead of + . + (main): Call `grub_pc_partition_map_init', + `grub_amiga_partition_map_init' and + `grub_apple_partition_map_init' and deinitialize afterwards. + * util/i386/pc/biosdisk.c: Include `#include + ' and `include ' instead of + `'. + * util/i386/pc/grub-setup.c: Likewise. + * util/i386/pc/biosdisk.c: Likewise. + (grub_util_biosdisk_get_grub_dev): Only access the PC specific + partition information in case of a PC partition. + * util/i386/pc/grub-setup.c: Include `#include + ' and `include ' instead of + `'. + (setup): Only access the PC specific partition information in case + of a PC partition. + +2004-11-17 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (grub_setjmp): Remove function. + (grub_longjmp): Likewise. + * include/grub/powerpc/setjmp.h (grub_jmp_buf): Set array size to + 20. + * normal/powerpc/setjmp.S: New file. + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add + `normal/powerpc/setjmp.S'. + (grubof_CFLAGS): Add `-DGRUBOF'. + * include/grub/setjmp.h [GRUB_UTIL]: Changed condition to + [GRUB_UTIL && !GRUBOF]. + +2004-11-16 Marco Gerards + + * kern/powerpc/ieee1275/openfw.c (grub_devalias_iterate): Skip any + property named `name'. Correctly handle the error returned by + `grub_ieee1275_finddevice' if a device can not be opened. + +2004-11-02 Hollis Blanchard + + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_readkey): Test + `actual' for negativity. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Remove + kern/fshelp.c. + +2004-11-01 Marco Gerards + + * term/i386/pc/vga.c (VGA_HEIGHT): Changed to 350. + (PAGE_OFFSET): New macro. + (CRTC_ADDR_PORT): Likewise. + (CRTC_DATA_PORT): Likewise. + (START_ADDR_HIGH_REGISTER): Likewise. + (START_ADDR_LOW_REGISTER): Likewise. + (GRAPHICS_ADDR_PORT): Likewise. + (GRAPHICS_DATA_PORT): Likewise. + (READ_MAP_REGISTER): Likewise. + (INPUT_STATUS1_REGISTER): Likewise. + (INPUT_STATUS1_VERTR_BIT): Likewise. + (page): New variable. + (wait_vretrace): New function. + (set_read_map): Likewise. + (set_start_address): Likewise. + (grub_vga_init): Use mode 0x10 instead of mode 0x12. Switch to + the right page. + (check_vga_mem): Take the page into account. + (write_char): Likewise. + (write_cursor): Likewise. + (scroll_up): Likewise. Copy the page to the page that is not + shown and switch between both pages. + (grub_vga_putchar): Fix off by one error. + (grub_vga_cls): Wait for the vertical retrace. Take the page into + account. + +2004-11-01 Marco Gerards + + Add support for iso9660 (including rockridge). + + * conf/i386-pc.rmk (grub_emu_SOURCES): Add fs/iso9660.c. + (iso9660_mod_SOURCES): New variable. + (iso9660_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/iso9660.c. + * include/grub/fs.h (grub_iso9660_init): New prototype. + * util/grub-emu.c (main): Call `grub_iso9660_init'. + * fs/iso9660.c: New file. + + * include/grub/misc.h (grub_strncat): New prototype. + * kern/misc.c (grub_strncat): New function. + + * fs/hfs.c (grub_hfs_mount): Translate the error + `GRUB_ERR_OUT_OF_RANGE' to `GRUB_ERR_BAD_FS'. + * fs/jfs.c (grub_jfs_mount): Likewise. + * fs/ufs.c (grub_ufs_mount): Likewise. + +2004-10-28 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (cmain): Remove asm statements + which initialized BAT registers. + * boot/powerpc/ieee1275/ieee1275.c (IEEE1275_CALL_ENTRY_FN, + grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON): + Move from here... + * include/grub/powerpc/ieee1275/ieee1275.h (IEEE1275_CALL_ENTRY_FN, + grub_ieee1275_common_hdr, INIT_IEEE1275_COMMON): + ... to here. + * kern/powerpc/ieee1275/openfw.c (grub_map): New function. + (grub_mapclaim): Likewise. + * loader/powerpc/ieee1275/linux.c (grub_load_linux): Use + grub_mapclaim instead of grub_ieee1275_claim. Assign linux_addr by + hand. + +2004-10-19 Hollis Blanchard + + * conf/powerpc-ieee1275.rmk (COMMON_ASFLAGS): Remove -fno-builtin. + (COMMON_CFLAGS): Remove -fno-builtin and -D__ASSEMBLY__. Add + -ffreestanding and -msoft-float. + +2004-10-15 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): Do not + append ":0" to devpath if the GRUB_IEEE1275_NO_PARTITION_0 flag is + set in grub_ieee1275_flags. + +2004-10-14 Hollis Blanchard + + * include/grub/powerpc/ieee1275/ieee1275.h (abort): Add function + prototype. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Call + grub_console_init first. + Change the memory range used for grub_ieee1275_claim and + grub_mm_init_region. + Print an error message if the claim fails. + Include . + +2004-10-13 Hollis Blanchard + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_iterate): + Call grub_children_iterate for device nodes of type `scsi', + `ide', or `ata'. + (grub_ofdisk_open): Remove manual device alias resolution. + Fix memory leak when device cannot be opened. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_children_iterate): New prototype. + * kern/powerpc/ieee1275/openfw.c (grub_children_iterate): + New function. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Return -1 if args.size was -1. + +2004-10-11 Hollis Blanchard + + * boot/powerpc/ieee1275/cmain.c (grub_ieee1275_flags): New global. + (cmain): Accept 3 parameters. Test for 0xdeadbeef, indicating Old + World Macintosh. If Old Wold, set flag in grub_ieee1275_flags; claim + Open Firmware's memory for it; claim memory from _start to _end. + * boot/powerpc/ieee1275/crt0.S (__bss_start): New extern. + (_end): New extern. + (_start): Zero BSS from __bss_start to _end. + * include/grub/powerpc/ieee1275/ieee1275.h (grub_ieee1275_flags): + New extern. + (GRUB_IEEE1275_NO_PARTITION_0): New #define. + +2004-10-11 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): Return + -1 if args.base was -1. + +2004-10-08 Hollis Blanchard + + * term/powerpc/ieee1275/ieee1275.c (grub_ofconsole_cls): Use an ANSI + escape sequence instead of a literal ^L. Also call + grub_ofconsole_gotoxy. + +2004-10-03 Hollis Blanchard + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_claim): change + void * arguments to grub_addr_t. All callers updated. Also make + the `result' argument optional. + (grub_ieee1275_release): change void * arguments to grub_addr_t. + All callers updated. + +2004-09-22 Hollis Blanchard + + * commands/ls.c (grub_ls_list_files): Use the string following the + initial ')', if present, as the filesystem path. + * kern/rescue.c (grub_rescue_cmd_ls): Likewise. + + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): List crt0.S first. + +2004-09-18 Yoshinori K. Okuji + + Make the source code of the menu interface more readable. + + * normal/menu.c: Include grub/mm.h. + (TERM_WIDTH): New macro. + (TERM_HEIGHT): Likewise. + (TERM_INFO_HEIGHT): Likewise. + (TERM_MARGIN): Likewise. + (TERM_SCROLL_WIDTH): Likewise. + (TERM_TOP_BORDER_Y): Likewise. + (TERM_LEFT_BORDER_X): Likewise. + (TERM_BORDER_WIDTH): Likewise. + (TERM_MESSAGE_HEIGHT): Likewise. + (TERM_BORDER_HEIGHT): Likewise. + (TERM_NUM_ENTRIES): Likewise. + (TERM_FIRST_ENTRY_Y): Likewise. + (TERM_ENTRY_WIDTH): Likewise. + (TERM_CURSOR_X): Likewise. + (draw_border): Use macros instead of magic numbers. + (print_entry): Likewise. + (print_entries): Likewise. + (run_menu): Likewise. Also, handle the key 'e'. + (run_menu_entry): Ignore empty command lines. + (print_message): Added a new argument EDIT. If EDIT is true, + print a different message. + (init_page): Likewise. + (edit_menu_entry): New function. Not implemented yet. + +2004-09-17 Marco Gerards + + Add `linux.mod' and `multiboot.mod' so linux and multiboot kernels + can be loaded from normal mode. + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `linux.mod' and + `multiboot.mod'. + (linux_mod_SOURCES, linux_mod_CFLAGS, multiboot_mod_SOURCES) + (multiboot_mod_CFLAGS): New variables. + * loader/i386/pc/linux_normal.c: New file. + * loader/i386/pc/multiboot_normal.c: Likewise. + + * loader/i386/pc/linux.c (grub_rescue_cmd_initrd): Don't use the + attribute `unused'. + + * fs/ext2.c (grub_ext2_iterate_dir): Fix typos in inode type. Use + `fdiro' to read the mode information from instead of `diro'. + + * fs/fshelp.c (grub_fshelp_find_file): Set type to foundtype after + looking up a symlink. + + * include/grub/normal.h (GRUB_COMMAND_FLAG_NO_ARG_PARSE): New + macro. + * normal/command.c (grub_command_execute): Don't parse the + arguments when `GRUB_COMMAND_FLAG_NO_ARG_PARSE' is set in the + flags of the command. + + * normal/menu.c (grub_menu_run): Fix typo. + +2004-09-14 Hollis Blanchard + + * kern/powerpc/ieee1275/init.c (abort): Trap into Open Firmware. + + * term/powerpc/ieee1275/ofconsole.c (grub_ofconsole_gotoxy): Use + `y + 1' instead of `y - 1'. + + * conf/powerpc-ieee1275.rmk (grubof_LDFLAGS): Add `-N' and `-S'. + +2004-09-14 Yoshinori K. Okuji + + From Hollis Blanchard : + * kern/misc.c (memmove): New alias for grub_memmove. + (memcmp): New alias for grub_memcmp. + (memset): New alias for grub_memset. + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_get_property): + Change "int handle" to "grub_ieee1275_phandle_t handle". + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_get_property): Likewise. + +2004-09-12 Tomas Ebenlendr + + Added normal mode command `chainloader' as module chain.mod, which + depends on normal.mod and _chain.mod. + + * conf/i386-pc.rmk (pkgdata_MODULES): Add `chain.mod'. + (chain_mod_SOURCES, chain_mod_CFLAGS): Variables added. + * include/grub/i386/pc/loader.h (grub_rescue_cmd_chainloader): + Deleted prototype. + * loader/i386/pc/chainloader.c (grub_rescue_cmd_chainloader): All + but arguments parsing moved to ... + (grub_chainloader_cmd): ... here. New function. + * include/grub/i386/pc/chainloader.h: New file. + * loader/i386/pc/chainloader_normal.c: Likewise. + +2004-09-11 Marco Gerards + + * conf/i386-pc.rmk (kernel_img_SOURCES): Added kern/fshelp.c. + (grub_mkimage_LDFLAGS): Likewise. + (grub_emu_SOURCES): Likewise. + (kernel_img_HEADERS): Added fshelp.h. + * fs/ext2.c: Include . + (FILETYPE_REG): New macro. + (FILETYPE_INO_REG): Likewise. + (grub_ext_sblock): Renamed to `grub_ext2_sblock'. + Changed all users. + (ext2_block_group): Renamed to `grub_ext2_block_group'. Changed + all users. + (grub_fshelp_node): New struct. + (grub_ext2_data): Added member `diropen'. Changed member `inode' + to a pointer. + (grub_ext2_get_file_block): Removed function. + (grub_ext2_read_block): New function. + (grub_ext2_read_file): Replaced parameter `data' by `node'. + This function was written. + (grub_ext2_mount): Read the root inode. Create a diropen struct. + (grub_ext2_find_file): Removed function. + (grub_ext2_read_symlink): New function. + (grub_ext2_iterate_dir): Likewise. + (grub_ext2_open): Rewritten. + (grub_ext2_dir): Rewritten. + * include/grub/fshelp.h: New file. + * fs/fshelp.c: Likewise. + +2004-09-10 Yoshinori K. Okuji + + * normal/menu.c: Include grub/loader.h and grub/machine/time.h. + (print_message): Add a missing newline. + (run_menu): Added timeout support. + (run_menu_entry): New local function. + (grub_menu_run): Added support for booting. + + * kern/loader.c (grub_loader_is_loaded): New function. + + * include/grub/powerpc/ieee1275/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/i386/pc/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/normal.h (struct grub_command_list): Remove + constant from the member `command'. + + * include/grub/loader.h (grub_loader_is_loaded): Declared. + + * include/grub/err.h (GRUB_ERR_INVALID_COMMAND): New constant. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/time.h. + +2004-08-28 Marco Gerards + + Add support for the JFS filesystem. + + * fs/jfs.c: New file. + * include/grub/fs.h (grub_jfs_init): New prototype. + (grub_jfs_fini): New prototype. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/jfs.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add jfs.mod. + (jfs_mod_SOURCES): New variable. + (jfs_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs.jfs.c. + (grubof_SOURCES): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize JFS support. + + * fs/fat.c (grub_fat_find_dir): Convert the filename little + endian to the host endian. + (grub_fat_utf16_to_utf8): Move function from there... + * kern/misc.c (grub_utf16_to_utf8): ...to here. Do not convert + the endianness of the source string anymore. + * include/grub/misc.h (grub_utf16_to_utf8): New prototype. + +2004-08-24 Marco Gerards + + * commands/boot.c (grub_boot_init) [GRUB_UTIL]: Make conditional. + (grub_boot_fini) [GRUB_UTIL]: Likewise. + (GRUB_MOD_INIT) [!GRUB_UTIL]: Likewise. + (GRUB_MOD_FINI) [!GRUB_UTIL]: Likewise. + + * fs/hfs.c (grub_hfs_find_node): Add a prototype for `node_found'. + (grub_hfs_iterate_dir): Make the function static. Add prototypes + for `node_found' and `it_dir'. + (grub_hfs_dir): Add prototype for `dir_hook'. + + * fs/minix.c (grub_minix_get_file_block): Add prototype for + `grub_get_indir'. Rename `indir' in two blocks to `indir16' + and `indir32' to silence a gcc warning. + + * include/grub/fs.h (grub_hfs_init): New prototype. + (grub_hfs_fini): Likewise. + + +2004-08-21 Yoshinori K. Okuji + + Each disk device has its own id now. This is useful to make use + of multiple disk devices. + + * include/grub/disk.h (grub_disk_dev_id): New enum. + (GRUB_DISK_DEVICE_BIOSDISK_ID): New constant. + (GRUB_DISK_DEVICE_OFDISK_ID): Likewise. + + * disk/i386/pc/biosdisk.c (grub_biosdisk_dev): Specify + GRUB_DISK_DEVICE_BIOSDISK_ID as an id. + + * disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_dev): Specify + GRUB_DISK_DEVICE_OFDISK_ID as an id. + + * util/i386/pc/biosdisk.c (grub_util_biosdisk_dev): Specify + GRUB_DISK_DEVICE_BIOSDISK_ID as an id. + + * include/grub/disk.h (struct grub_disk_dev): Added a new member + "id" which is used by the cache manager. + + * normal/main.c (grub_normal_init_page): Use "GNU GRUB" instead + of just "GRUB". + +2004-08-18 Marco Gerards + + * fs/hfs.c: New file. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/hfs.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add hfs.mod. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/hfs.c. + (grubof_SOURCES): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize HFS support. + + * include/grub/misc.h (grub_strncasecmp): Add prototype. + * kern/misc.c (grub_strncasecmp): Add function. + +2004-08-14 Marco Gerards + + * include/grub/arg.h (GRUB_ARG_OPTION_OPTIONAL): Surround macro + with parentheses. + + * fs/ext2.c (FILETYPE_UNKNOWN): New macro. + (grub_ext2_dir): In case the directory entry type is unknown, read + it from the inode. + +2004-08-02 Peter Bruin + + * loader/powerpc/ieee1275/linux.c (grub_linux_init): Pass + grub_load_linux instead of grub_rescue_cmd_linux as second + argument of grub_rescue_register_command. + + * Makefile.in (RMKFILES): Add conf/powerpc-ieee1275.rmk. + +2004-07-27 Marco Gerards + + * boot/powerpc/ieee1275/ieee1275.c (grub_ieee1275_release): New + function. + * commands/boot.c: Remove the check for `GRUB_UTIL'. + * conf/powerpc-ieee1275.rmk (grubof_SOURCES): Add + `loader/powerpc/ieee1275/linux.c', + `loader/powerpc/ieee1275/linux_normal.c' and `commands/boot.c'. + * include/grub/powerpc/ieee1275/ieee1275.h + (grub_ieee1275_release): New prototype. + * include/grub/powerpc/ieee1275/loader.h: Rewritten. + * kern/powerpc/ieee1275/init.c (grub_machine_init): Initialize + normal, boot, linux and linux_normal. + * loader/powerpc/ieee1275/linux.c: New file. + * loader/powerpc/ieee1275/linux_normal.c: Likewise. + +2004-07-12 Marco Gerards + + * normal/arg.c (grub_arg_parse): Correct error handling after + reallocating the argumentlist (check if `argl' is not null instead + of checking if `args' is not null). + * kern/mm.c (grub_realloc): Return the same pointer when using the + same region, instead of returning the header address. + +2004-07-11 Marco Gerards + + * disk/powerpc/ieee1275/partition.c (grub_partition_iterate): Skip + one block instead of two when looking for the initial partition. + (grub_partition_probe): Initialize the local variable `p' with 0. + Use base 10 for the grub_strtoul call. + * kern/misc.c (grub_strncpy): Fix off by one bug. Eliminated the + need for one local variable. + (grub_strtoul): Don't add the new value to `num', instead of that + just assign it. + +2004-07-11 Marco Gerards + + * conf/i386-pc.rmk (pkgdata_IMAGE): Add pxeboot.img. + (pxeboot_img_SOURCES): New variable. + (pxeboot_img_ASFLAGS): Likewise. + (pxeboot_img_LDFLAGS): Likewise. + * boot/i386/pc/pxeboot.S: New file. Based on pxeloader.S from + GRUB Legacy and boot.S. Adopted for GRUB 2 by lode leroy + . + +2004-06-27 Tomas Ebenlendr + + * kern/rescue.c (grub_enter_rescue_mode): Don't continue when + there was no input. + +2004-06-27 Tomas Ebenlendr + + * normal/cmdline.c (grub_set_history): Fix off by one bug. Fixed + the history buffer logic. + +2004-06-27 Tomas Ebenlendr + + * fs/ext2.c (FILETYPE_INO_MASK, FILETYPE_INO_DIRECTORY) + (FILETYPE_INO_SYMLINK): New macros. + (grub_ext2_find_file): Check if the node is a directory using the + inode stat information instead of using the filetype in the + dirent. Exclude the first character of an absolute symlink. + (grub_ext2_dir): Mask out the filetype part of the mode member of + the inode. + +2004-05-24 Marco Gerards + + Add support for UFS version 1 and 2. Add support for the minix + filesystem version 1 and 2, both the variants with 14 and 30 long + filenames. + + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/ufs.c and + fs/minix.c. + (grub_emu_SOURCES): Likewise. + (pkgdata_MODULES): Add ufs.mod and minix.mod. + (ufs_mod_SOURCES): New variable. + (ufs_mod_CFLAGS): Likewise. + (minix_mod_SOURCES): Likewise. + (minix_mod_CFLAGS): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add fs/ufs.c and + fs/minix.c. + (grubof_SOURCES): Likewise. + * fs/ufs.c: New file. + * fs/minix.c: New file. + * include/grub/fs.h (grub_ufs_init): New prototype. + (grub_ufs_fini): Likewise. + (grub_minix_init): Likewise. + (grub_minix_fini): Likewise. + * util/grub-emu.c (main): Initialize and deinitialize UFS and + minix fs. + +2004-04-30 Jeroen Dekkers + + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Add normal/arg.c, + commands/ls.c, commands/terminal.c, commands/boot.c, + commands/cmp.c and commands/cat.c. + (grubof_LDFLAGS): Add -nostdlib -static-libgcc -lgcc. + + * kern/powerpc/ieee1275/init.c: Include "grub/env.h" instead of + "env.h" + +2004-04-04 Yoshinori K. Okuji + + All symbols prefixed with PUPA_ and pupa_ are renamed to GRUB_ + and grub_, respectively. Because the conversion is trivial and + mechanical, I omit the details here. Please refer to the CVS + if you need more information. + +2004-04-04 Yoshinori K. Okuji + + * include/pupa: Renamed to ... + * include/grub: ... this. + * util/i386/pc/pupa-mkimage.c: Renamed to ... + * util/i386/pc/grub-mkimage.c: ... this. + * util/i386/pc/pupa-setup.c: Renamed to ... + * util/i386/pc/grub-setup.c: ... this. + * util/pupa-emu.c: Renamed to ... + * util/grub-emu.c: ... this. + +2004-03-29 Marco Gerards + + Add support for the newworld apple macintosh (PPC). This has been + tested on the powerbook 2000 only. It only adds support for + generic ieee1275 functions, console and disk support. This should + be easy to port to other architectures with support for Open + Firmware. + + * configure.ac: Accept the powerpc as host_cpu. In the case of + the powerpc cpu set the host_vendor to ieee1275. Make sure the i386 + specific tests are only executed while building for the i386. + Inverse test for crosscompile. + * genmk.rb (Utility): Allow assembler files. + * normal/cmdline.c (pupa_tab_complete): Reset pupa_errno. + * conf/powerpc-ieee1275.rmk: New file. + * disk/powerpc/ieee1275/ofdisk.c: Likewise. + * disk/powerpc/ieee1275/partition.c: Likewise. + * include/pupa/powerpc/ieee1275/biosdisk.h: Likewise. + * include/pupa/powerpc/ieee1275/console.h: Likewise. + * include/pupa/powerpc/ieee1275/partition.h: Likewise. + * include/pupa/powerpc/ieee1275/time.h: Likewise. + * include/pupa/powerpc/ieee1275/util/biosdisk.h: Likewise. + * include/pupa/powerpc/ieee1275/multiboot.h: Likewise. + * include/pupa/powerpc/ieee1275/loader.h + * include/pupa/powerpc/setjmp.h: Likewise. + * include/pupa/powerpc/types.h: Likewise. + * kern/powerpc/ieee1275/init.c: Likewise. + * kern/powerpc/ieee1275/openfw.c: Likewise. + * term/powerpc/ieee1275/ofconsole.c: Likewise. + + These files were written by Johan Rydberg + (jrydberg@night.trouble.net) and I only modified them slightly. + + * boot/powerpc/ieee1275/cmain.c: New file. + * boot/powerpc/ieee1275/crt0.S: Likewise. + * boot/powerpc/ieee1275/ieee1275.c: Likewise. + * include/pupa/powerpc/ieee1275/ieee1275.h: Likewise. + +2004-03-14 Jeroen Dekkers + + * Makefile.in: Update copyright. + * genmodsrc.sh: Likewise. + * gensymlist.sh: Likewise. + * term/i386/pc/vga.c: Indent correctly. + + * util/i386/pc/pupa-mkimage.c (usage): Use PACKAGE_BUGREPORT as + bugreporting address. + * util/i386/pc/pupa-setup.c (usage): Likewise, + (main): Call pupa_ext2_init and pupa_ext2_fini. + + * fs/fat.c (log2): Renamed to ... + (fat_log2): ... this. + All callers changed. + * kern/misc.c (memcpy): Alias to pupa_memmove. + * loader/i386/pc/multiboot.c (pupa_rescue_cmd_multiboot): Fix + lvalue cast. + * util/console.c (pupa_ncurses_fini): Return 0. + + * util/i386/pc/biosdisk.c (pupa_util_biosdisk_open)[__linux__]: + Move fail label here. + [__GNU__]: Don't warn when using stat. + (open_device)[!__linux__]: Check if FD < 0 instead of !FD. + (pupa_util_biosdisk_get_pupa_dev)[__GNU__]: Change type of N to + long int. Use strtol instead of strtoul. + +2004-03-14 Marco Gerards + + * commands/boot.c: New file. + * commands/cat.c: Likewise. + * commands/cmp.c: Likewise. + * commands/ls.c: Likewise. + * commands/terminal.c: Likewise. + * normal/command.c: Include and . + (pupa_register_command): Changed interface to match the new + argument parser. + (pupa_command_execute): Changed (almost rewritten) so it uses + pupa_split_command. Added support for setting variables using the + syntax `foo=bar'. + (rescue_command): Changed to work with the new argument parser. + (terminal_command): Moved from here to commands/terminal.c. + (set_command): New function. + (unset_command): New function. + (insmod_command): New function. + (rmmod_command): New function. + (lsmod_command): New function. + (pupa_command_init): Don't initialize the command terminal + anymore. Initialize the commands set, unset, insmod, rmmod and + lsmod. + * conf/i386-pc.rmk (kernel_img_SOURCES): Add kern/env.c. + (kernel_img_HEADERS): Add arg.h and env.h. + (pupa_mkimage_LDFLAGS): Add kern/env.c. + (pupa_emu_SOURCES): Add kern/env.c, commands/ls.c, + commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c, + normal/arg.c. + (pkgdata_MODULES): Add ls.mod, boot.mod, cmp.mod, cat.mod and + terminal.mod. + (normal_mod_SOURCES): Add normal/arg.c and normal/arg.c. + (boot_mod_SOURCES): New variable. + (terminal_mod_SOURCES): Likewise. + (ls_mod_SOURCES): Likewise. + (cmp_mod_SOURCES): Likewise. + (cat_mod_SOURCES): Likewise. + + * normal/arg.c: New file. + * kern/env.c: Likewise. + * include/pupa/arg.h: Likewise. + * include/pupa/env.h: Likewise. + * font/manager.c (font_command): Changed to match argument parsing + interface changes. + (PUPA_MOD_INIT): Likewise. + * hello/hello.c (pupa_cmd_hello): Likewise. + (PUPA_MOD_INIT): Likewise. + * include/pupa/disk.h: Include . + (pupa_print_partinfo): New prototype. + * include/pupa/dl.h (pupa_dl_set_prefix): Prototype removed. + (pupa_dl_get_prefix): Likewise. + * include/pupa/misc.h: Include . + (pupa_isgraph): New prototype. + (pupa_isdigit): Likewise. + (pupa_split_cmdline): Likewise. + * include/pupa/normal.h: Include . + (pupa_command): Changed the prototype of the member `func' to + match the argument parsing interface. Added member `options'. + (pupa_register_command): Updated to match function. + (pupa_arg_parse): New prototype. + (pupa_hello_init) [PUPA_UTIL]: New prototype. + (pupa_hello_fini) [PUPA_UTIL]: Likewise. + (pupa_ls_init) [PUPA_UTIL]: Likewise. + (pupa_ls_fini) [PUPA_UTIL]: Likewise. + (pupa_cat_init) [PUPA_UTIL]: Likewise. + (pupa_cat_fini) [PUPA_UTIL]: Likewise. + (pupa_boot_init) [PUPA_UTIL]: Likewise. + (pupa_boot_fini) [PUPA_UTIL]: Likewise. + (pupa_cmp_init) [PUPA_UTIL]: Likewise. + (pupa_cmp_fini) [PUPA_UTIL]: Likewise. + (pupa_terminal_init) [PUPA_UTIL]: Likewise. + (pupa_terminal_fini) [PUPA_UTIL]: Likewise. + * kern/disk.c: Include . + (pupa_print_partinfo): New function. + * kern/dl.c: Include . + (pupa_dl_dir): Variable removed. + (pupa_dl_load): Use the environment variable `prefix' instead of + the variable pupa_dl_dir. + (pupa_dl_set_prefix): Function removed. + (pupa_dl_get_prefix): Likewise. + * kern/i386/pc/init.c: Include . + (pupa_machine_init): Use the environment variable `prefix' instead of + using pupa_dl_set_prefix to set the prefix. + * kern/main.c: Include . + (pupa_set_root_dev): Use the environment variable `prefix' instead of + using pupa_dl_get_prefix to get the prefix. + * kern/misc.c: Include . + (pupa_isdigit): New function. + (pupa_isgraph): Likewise. + (pupa_ftoa): Likewise. + (pupa_vsprintf): Added support for printing values of the type + `double'. Make it possible to format variable output when using + formatting like `%1.2%f'. + (pupa_split_cmdline): New function. + * kern/rescue.c: Include . + (next_word): Removed function. + (pupa_rescue_cmd_prefix): Likewise. + (pupa_rescue_cmd_set): New function. + (pupa_rescue_cmd_unset): New function. + (pupa_enter_rescue_mode): Use the `pupa_split_cmdline' function to + split the command line instead of splitting it here. Added + support for setting variables using the syntax `foo=bar'. Don't + initialize the prefix command anymore. Initialized the set and + unset commands. + * normal/cmdline.c: Include . + (pupa_tab_complete): Added prototypes for print_simple_completion, + print_partition_completion, add_completion, iterate_commands, + iterate_dev, iterate_part and iterate_dir. Moved code to print + partition information from here to kern/disk.c. + (pupa_cmdline_run): Don't check if the function exists anymore. + * normal/main.c: Include . + (pupa_rescue_cmd_normal): Use the environment variable `prefix' + instead of using pupa_dl_get_prefix to get the prefix. + * term/i386/pc/vga.c: Include . + (check_vga_mem): Cast pointers to `void *' to silence a gcc + warning. + (pupa_vga_putchar) [! DEBUG_VGA]: Removed for this case. + (pupa_vga_setcolor): Declare unused variables with `__attribute__ + ((unused))' to silence a gcc warning. + (pupa_vga_setcolor): Likewise. + (debug_command): Changed to match argument parsing + interface changes. + * util/pupa-emu.c: Include . + (options): Added 0's for unused fields to silence a gcc warning. + (argp): Likewise. + (main): Use the environment variable `prefix' instead of using + pupa_dl_set_prefix to set the prefix. Initialize the commands ls, + boot, cmp, cat and terminal. Finish the commands boot, cmp, cat + and terminal. + + * util/i386/pc/getroot.c: Include . + * util/misc.c: Include . + (pupa_malloc): Rewritten so errors are correctly reported. + (pupa_realloc): Likewise. + (pupa_memalign): Likewise. + (pupa_mm_init_region): Declare unused variables with + `__attribute__ ((unused))' to silence a gcc warning. + * normal/i386/setjmp.S: Remove tab at the end of the file to + silence a gcc warning. + * loader/i386/pc/linux.c (pupa_rescue_cmd_initrd): Declare unused + variables with `__attribute__ ((unused))' to silence a gcc + warning. + * loader/i386/pc/multiboot.c (pupa_multiboot_unload): Make the + local variable i unsigned to silence a gcc warning. + + * kern/term.c: Include . + (pupa_more_lines): New variable. + (pupa_more): Likewise. + (pupa_putcode): When the pager is active pause at the end of every + screen. + (pupa_set_more): New function. + * include/pupa/term.h (pupa_set_more): New prototype. + + +2004-03-07 Yoshinori K. Okuji + + Now this project is GRUB 2 rather than PUPA. The location of + the CVS repository was moved to GRUB's. + + * configure.ac: Use bug-grub as the reporting address. + Use GRUB instead of PUPA. + Change the version number to 1.90. + +2004-02-24 Yoshinori K. Okuji + + * genkernsyms.sh: Updated copyright information. + * genmk.rb: Likewise. + * genmodsrc.sh: Likewise. + * gensymlist.sh: Likewise. + * boot/i386/pc/boot.S: Likewise. + * boot/i386/pc/diskboot.S: Likewise. + * disk/i386/pc/biosdisk.c: Likewise. + * disk/i386/pc/partition.c: Likewise. + * font/manager.c: Likewise. + * fs/ext2.c: Likewise. + * fs/fat.c: Likewise. + * include/pupa/boot.h: Likewise. + * include/pupa/device.h: Likewise. + * include/pupa/disk.h: Likewise. + * include/pupa/dl.h: Likewise. + * include/pupa/elf.h: Likewise. + * include/pupa/err.h: Likewise. + * include/pupa/file.h: Likewise. + * include/pupa/font.h: Likewise. + * include/pupa/fs.h: Likewise. + * include/pupa/kernel.h: Likewise. + * include/pupa/loader.h: Likewise. + * include/pupa/misc.h: Likewise. + * include/pupa/mm.h: Likewise. + * include/pupa/net.h: Likewise. + * include/pupa/normal.h: Likewise. + * include/pupa/rescue.h: Likewise. + * include/pupa/setjmp.h: Likewise. + * include/pupa/symbol.h: Likewise. + * include/pupa/term.h: Likewise. + * include/pupa/types.h: Likewise. + * include/pupa/i386/setjmp.h: Likewise. + * include/pupa/i386/types.h: Likewise. + * include/pupa/i386/pc/biosdisk.h: Likewise. + * include/pupa/i386/pc/boot.h: Likewise. + * include/pupa/i386/pc/console.h: Likewise. + * include/pupa/i386/pc/init.h: Likewise. + * include/pupa/i386/pc/kernel.h: Likewise. + * include/pupa/i386/pc/linux.h: Likewise. + * include/pupa/i386/pc/loader.h: Likewise. + * include/pupa/i386/pc/memory.h: Likewise. + * include/pupa/i386/pc/multiboot.h: Likewise. + * include/pupa/i386/pc/partition.h: Likewise. + * include/pupa/i386/pc/time.h: Likewise. + * include/pupa/i386/pc/vga.h: Likewise. + * include/pupa/i386/pc/util/biosdisk.h: Likewise. + * include/pupa/util/getroot.h: Likewise. + * include/pupa/util/misc.h: Likewise. + * include/pupa/util/resolve.h: Likewise. + * kern/device.c: Likewise. + * kern/disk.c: Likewise. + * kern/dl.c: Likewise. + * kern/err.c: Likewise. + * kern/file.c: Likewise. + * kern/fs.c: Likewise. + * kern/loader.c: Likewise. + * kern/main.c: Likewise. + * kern/misc.c: Likewise. + * kern/mm.c: Likewise. + * kern/rescue.c: Likewise. + * kern/term.c: Likewise. + * kern/i386/dl.c: Likewise. + * kern/i386/pc/init.c: Likewise. + * kern/i386/pc/lzo1x.S: Likewise. + * kern/i386/pc/startup.S: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot.c: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/i386/setjmp.S: Likewise. + * term/i386/pc/console.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * util/console.c: Likewise. + * util/genmoddep.c: Likewise. + * util/misc.c: Likewise. + * util/pupa-emu.c: Likewise. + * util/resolve.c: Likewise. + * util/unifont2pff.rb: Likewise. + * util/i386/pc/biosdisk.c: Likewise. + * util/i386/pc/getroot.c: Likewise. + * util/i386/pc/pupa-mkimage.c: Likewise. + * util/i386/pc/pupa-setup.c: Likewise. + +2004-02-15 Jeroen Dekkers + + * fs/ext2.c (pupa_ext2_read_file): Correct the value of BLOCKEND + when it is EXT2_BLOCK_SIZE (data). New argument READ_HOOK, all + callers changed. Set DATA->DISK->READ_HOOK to READ_HOOK before + reading and reset it after reading. + (pupa_ext2_close): Return PUPA_ERR_NONE. + + * include/pupa/i386/pc/linux.h (PUPA_LINUX_INITRD_MAX_ADDRESS): + Correct value. + (struct linux_kernel_header): Add kernel_version and + initrd_addr_max. + * loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Check whether + pupa_file_read succeeds. + (pupa_rescue_cmd_initrd): Implement. + +2003-12-03 Marco Gerards + + * fs/ext2.c (pupa_ext2_label): New function. + (pupa_ext2_fs): Added label. + * fs/fat.c (pupa_fat_label): New function. + (pupa_fat_fs): Added label. + * include/pupa/fs.h (struct pupa_fs): Added prototype label. + + * kern/misc.c (pupa_strndup): New function. + * include/pupa/misc.h (pupa_strndup): New prototype. + + * include/pupa/normal.h: Include . + (pupa_set_history): New prototype. + (pupa_iterate_commands): New prototype. + * normal/cmdline.c: Include , + , . + (hist_size): New variable. + (hist_lines): Likewise. + (hist_end): Likewise. + (hist_used): Likewise. + (pupa_set_history): New function. + (pupa_history_get): Likewise. + (pupa_history_add): Likewise. + (pupa_history_replace): Likewise. + (pupa_tab_complete): Likewise. + (pupa_cmdline_run): Added tab completion and history buffer. Tab + completion shows partitionnames while completing partitions, this + feature was suggested by Jeff Bailey. + * normal/command.c (pupa_iterate_commands): New function. + * normal/main.c (PUPA_DEFAULT_HISTORY_SIZE): New macro. + (pupa_normal_init): Initialize history buffer. + (PUPA_MOD_INIT): Likewise. + (pupa_normal_fini): Free the history buffer. + (PUPA_MOD_FINI): Likewise. + + * util/console.c (pupa_ncurses_getkey): Accept 127 as backspace + key. + + * aclocal.m4 (pupa_I386_CHECK_REGPARM_BUG): New DEFUN. + * configure.ac [i386]: Check for regparam bug. + (NESTED_FUNC_ATTR) [! i386]: Defined. + +2003-11-17 Marco Gerards + + * conf/i386-pc.rmk (sbin_UTILITIES): Added pupa-emu. + (pupa_setup_SOURCES): Added util/i386/pc/getroot.c. + (pupa_emu_SOURCES): New variable. + (pupa_emu_LDFLAGS): Likewise. + * include/pupa/fs.h (pupa_ext2_init) [PUPA_UTIL]: New prototype. + (pupa_ext2_fini) [PUPA_UTIL]: Likewise. + * include/pupa/normal.h (pupa_normal_init) [PUPA_UTIL]: Likewise. + (pupa_normal_fini) [PUPA_UTIL]: Likewise. + * include/pupa/setjmp.h [PUPA_UTIL]: Include . + (pupa_jmp_buf): New typedef. + (pupa_setjmp) [PUPA_UTIL]: New macro. + (pupa_longjmp) [PUPA_UTIL]: Likewise. + * include/pupa/term.h (struct pupa_term): New member `refresh'. + (pupa_refresh): New prototype. + * include/pupa/util/getroot.h: New file. + * kern/misc.c (pupa_vsprintf): Refresh the screen after updating + it. + * kern/rescue.c (pupa_rescue_get_command_line): Likewise. + (pupa_rescue_cmd_cat): Likewise. + (pupa_rescue_cmd_ls): Likewise. + (pupa_rescue_cmd_testload): Likewise. + (pupa_rescue_cmd_lsmod): Likewise. + * normal/cmdline.c (pupa_cmdline_get): Likewise. + * normal/menu.c (run_menu): Likewise. + * kern/term.c (pupa_cls): Likewise. + (pupa_refresh): New function. + * normal/normal.c (pupa_normal_init) [PUPA_UTIL]: New function. + (pupa_normal_fini) [PUPA_UTIL]: Likewise. + * util/console.c: New file. + + * util/i386/pc/getroot.c: New file. + * util/i386/pc/pupa-setup.c: Include . + (pupa_putchar): New function. + (pupa_refresh): Likewise. + (xgetcwd): Function moved to ... + (strip_extra_slashes): Likewise. + (get_prefix): Likewise. + * util/i386/pc/getroot.c: ... here. + (find_root_device): Function moved and renamed to... + * util/i386/pc/getroot.c (pupa_find_root_device): ... here. + Changed all callers. + * util/i386/pc/pupa-setup.c (guess_root_device): Function moved + and renamed to... + * util/i386/pc/getroot.c (pupa_guess_root_device): ... here. + Changed all callers. + * util/misc.c (pupa_memalign): New function. + (pupa_mm_init_region): Likewise. + (pupa_register_exported_symbols): Likewise. + (pupa_putchar): Function removed. + * util/pupa-emu.c: New file. + +2003-11-16 Jeroen Dekkers + + * conf/i386-pc.rmk (pkgdata_MODULES): Add _multiboot.mod. + (_multiboot_mod_SOURCES): New variable. + (_multiboot_mod_CFLAGS): Likewise. + * loader/i386/pc/multiboot.c: New file. + * include/pupa/i386/pc/multiboot.h: Likewise. + * kern/i386/pc/startup.S: Include pupa/machine/multiboot.h. + (pupa_multiboot_real_boot): New function. + * include/pupa/i386/pc/loader.h: Include pupa/machine/multiboot.h. + (pupa_multiboot_real_boot): New prototype. + (pupa_rescue_cmd_multiboot): Likewise + (pupa_rescue_cmd_module): Likewise. + + * kern/loader.c (pupa_loader_set): Continue when + pupa_loader_unload_func() fails. + (pupa_loader_unset): New function. + * include/pupa/loader.h (pupa_loader_unset): New prototype. + + * kern/misc.c (pupa_stpcpy): New function. + * include/pupa/misc.h (pupa_stpcpy): New prototype. + +2003-11-12 Marco Gerards + + * disk/i386/pc/biosdisk.c (pupa_biosdisk_open): Correctly check + for available extensions. + + * include/pupa/i386/pc/time.h: New file. + * kern/disk.c: Include . + (PUPA_CACHE_TIMEOUT): New macro. + (pupa_last_time): New variable. + (pupa_disk_open): Flush the cache when there was a timeout. + (pupa_disk_close): Reset the timer. + * kern/i386/pc/startup.S (pupa_get_rtc): Renamed from + pupa_currticks. + * util/misc.c: Include + (pupa_get_rtc): New function. + +2003-11-09 Jeroen Dekkers + + * fs/ext2.c (struct pupa_ext2_inode): Declare struct datablocks + as blocks. + (pupa_ext2_get_file_block): Use blocks member. + + * fs/ext2.c (pupa_ext2_read_file): Only set skipfirst for the + first block. Return -1 instead of pupa_errno on error. + +2003-10-27 Marco Gerards + + * README: In the pupa-mkimage example use _chain instead of chain + and ext2 instead of fat. + * TODO: Replace ext2fs with jfs as an example. Add an item for + adding journal playback for ext2fs. + * conf/i386-pc.rmk (pupa_setup_SOURCES): Added fs/ext2.c. + (pkgdata_MODULES): Added ext2.mod. + (ext2_mod_SOURCES): New variable. + (ext2_mod_CFLAGS): Likewise. + * include/pupa/err.h (pupa_err_t): Added PUPA_ERR_SYMLINK_LOOP. + * include/pupa/misc.h (pupa_strncpy): New prototype. + (pupa_strcat): Likewise. + (pupa_strncmp): Likewise. + * kern/misc.c (pupa_strcat): Enable function. + (pupa_strncpy): New function. + (pupa_strncmp): Likewise. + * fs/ext2.c: New file. + + * kern/disk.c (pupa_disk_read): Set pupa_errno to PUPA_ERR_NONE + when the read failed before retrying. + * util/i386/pc/biosdisk.c (_LARGEFILE_SOURCE): Removed. + (_FILE_OFFSET_BITS): Likewise. + * configure.ac: Added AC_SYS_LARGEFILE. + +2003-09-25 Yoshinori K. Okuji + + * genmk.rb (PModule#rule): Make sure to get only symbol names + from the output of nm. + Reported by Robert Millan . + +2003-09-25 Yoshinori K. Okuji + + I forgot to check in these changes for a long time. This adds + incomplete support for VGA console, and this is still very + buggy. Also, a lot of consideration is required for I18N, + UNICODE, and VGA font issues. Therefore, assume that this is + such that "better than nothing". + + * font/manager.c: New file. + * include/pupa/font.h: Likewise. + * include/pupa/i386/pc/vga.h: Likewise. + * term/i386/pc/vga.c: Likewise. + * util/unifont2pff.rb: Likewise. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/vga.h. + (pkgdata_MODULES): Added vga.mod and font.mod. + (vga_mod_SOURCES): New variables. + (vga_mod_CFLAGS): Likewise. + (font_mod_SOURCES): Likewise. + (font_mod_CFLAGS): Likewise. + + * include/pupa/err.h (PUPA_ERR_BAD_FONT): New constant. + + * include/pupa/term.h: Include pupa/err.h. + (struct pupa_term): Added init and fini. + Changed the argument of putchar to pupa_uint32_t. + + * include/pupa/i386/pc/console.h: Include pupa/symbol.h. + (pupa_console_real_putchar): New prototype. + (pupa_console_putchar): Removed. + (pupa_console_checkkey): Exported. + (pupa_console_getkey): Likewise. + + * kern/misc.c (pupa_vsprintf): Add support for UNICODE + characters. + + * kern/term.c (pupa_term_set_current): Rewritten. + (pupa_putchar): Likewise. + (pupa_putcode): New function. + + * kern/i386/pc/startup.S (pupa_console_putchar): Renamed to ... + (pupa_console_real_putchar): ... this. + (pupa_vga_set_mode): New function. + (pupa_vga_get_font): Likewise. + + * normal/command.c: Include pupa/term.h. + (terminal_command): New function. + (pupa_command_init): Register the command "terminal". + + * normal/menu.c (DISP_LEFT): Changed to a UNICODE value. + (DISP_UP): Likewise. + (DISP_RIGHT): Likewise. + (DISP_DOWN): Likewise. + (DISP_HLINE): Likewise. + (DISP_VLINE): Likewise. + (DISP_UL): Likewise. + (DISP_UR): Likewise. + (DISP_LL): Likewise. + (DISP_LR): Likewise. + + * term/i386/pc/console.c (pupa_console_putchar): New function. + +2003-02-08 NIIBE Yutaka + + * util/resolve.c (pupa_util_resolve_dependencies): BUG + FIX. Reverse the path_list. + + * include/pupa/normal.h: Export pupa_register_command and + pupa_unregister_command. + + * hello/hello.c (pupa_cmd_hello): New module. + * conf/i386-pc.rmk: Added hello.mod. + +2003-01-31 Yoshinori K. Okuji + + * kern/i386/pc/lzo1x.S: New file. + + * util/i386/pc/pupa-mkimage.c: Include lzo1x.h. + (compress_kernel): New variable. + (generate_image): Heavily modified to support compressing a + large part of the core image. + + * util/misc.c (pupa_util_read_image): Fix a file descriptor + leak. + (pupa_util_load_image): New function. + + * kern/i386/pc/startup.S: Include pupa/machine/kernel.h. + (pupa_compressed_size): New variable. + (codestart): Enable Gate A20 here. + Decompress the compressed part of the core image. + Rearrange the code to put functions and variables which are + required for initialization in the non-compressed part. + Include lzo1x.S. + + * kern/i386/pc/init.c (pupa_machine_init): Don't enable Gate A20 + here. + + * include/pupa/util/misc.h (pupa_util_write_image): Declared. + + * include/pupa/i386/pc/kernel.h + (PUPA_KERNEL_MACHINE_COMPRESSED_SIZE): New macro. + (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): Increased by 4. + (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise. + (PUPA_KERNEL_MACHINE_PREFIX): Likewise. + (PUPA_KERNEL_MACHINE_RAW_SIZE): New macro. + + * conf/i386-pc.rmk (pupa_mkimage_LDFLAGS): New variable. + + * genmk.rb (Image#rule): Put LDFLAGS at the end of a line. + (Utility#rule): Likewise. + + * configure.ac: Check if LZO is available. + +2003-01-20 Yoshinori K. Okuji + + * include/pupa/normal.h: New file. + * include/pupa/setjmp.h: Likewise. + * include/pupa/i386/setjmp.h: Likewise. + * normal/cmdline.c: Likewise. + * normal/command.c: Likewise. + * normal/main.c: Likewise. + * normal/menu.c: Likewise. + * normal/i386/setjmp.S: Likewise. + + * loader/i386/pc/linux.c (pupa_rescue_cmd_linux): Made global. + (pupa_rescue_cmd_initrd): Likewise. + + * loader/i386/pc/chainloader.c (pupa_rescue_cmd_chainloader): + Likewise. + + * kern/i386/pc/startup.S (translation_table): New variable. + (translate_keycode): New function. + (pupa_console_getkey): Call translate_keycode. + + * kern/rescue.c (attempt_normal_mode): New function. + (pupa_enter_rescue_mode): Attempt to execute the normal mode. If + it failed, print a message. + + * kern/mm.c (pupa_real_malloc): Print more information when a + free magic is broken. + (pupa_free): If the first free header is not free actually, set + it to P. + + * kern/main.c (pupa_load_normal_mode): Just load the module + "normal". + (pupa_main): Don't print the message + "Entering into rescue mode..." here. + + * include/pupa/i386/pc/loader.h (pupa_rescue_cmd_initrd): + Declared. + (pupa_rescue_cmd_initrd): Likewise. + (pupa_rescue_cmd_initrd): Likewise. + + * include/pupa/symbol.h (FUNCTION): Specify the type. + (VARIABLE): Likewise. + + * include/pupa/err.h (pupa_err_t): Added + PUPA_ERR_UNKNOWN_COMMAND. + + * include/pupa/dl.h (pupa_dl_set_prefix): Exported. + (pupa_dl_get_prefix): Likewise. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added normal.mod. + Added _chain.mod and _linux.mod instead of chain.mod and + linux.mod. + (chain_mod_SOURCES): Renamed to ... + (_chain_mod_SOURCES): ... this. + (chain_mod_CFLAGS): Renamed to ... + (_chain_mod_CFLAGS): ... this. + (linux_mod_SOURCES): Renamed to ... + (_linux_mod_SOURCES): ... this. + (linux_mod_CFLAGS): Renamed to ... + (_linux_mod_CFLAGS): ... this. + (normal_mod_SOURCES): New variable. + (normal_mod_CFLAGS): Likewise. + (normal_mod_ASFLAGS): Likewise. + +2003-01-18 Yoshinori K. Okuji + + * kern/rescue.c (pupa_rescue_cmd_rmmod): Call pupa_dl_unload, if + possible. + + * kern/dl.c (pupa_dl_ref): Refer depending modules + recursively. + (pupa_dl_unref): Unrefer depending modules recursively. + Don't call pupa_dl_unload implicitly, because PUPA can crash if + a module is unloaded before one depending on that module is + unloaded. + (pupa_dl_unload): Unload depending modules explicitly, + if possible. + +2003-01-17 Yoshinori K. Okuji + + * include/pupa/i386/pc/linux.h: New file. + * loader/i386/pc/linux.c: Likewise. + + * loader/i386/pc/chainloader.c (pupa_chainloader_boot_sector): + Removed. + (pupa_chainloader_unload): Return PUPA_ERR_NONE. + (pupa_rescue_cmd_chainloader): Read the image to 0x7C00 instead + of PUPA_CHAINLOADER_BOOT_SECTOR. + + * kern/i386/pc/startup.S: Include pupa/machine/linux.h. + (pupa_linux_prot_size): New variable. + (pupa_linux_tmp_addr): Likewise. + (pupa_linux_real_addr): Likewise. + (pupa_linux_boot_zimage): New function. + (pupa_linux_boot_bzimage): Likewise. + + * kern/i386/pc/init.c (struct mem_region): New structure. + (MAX_REGIONS): New macro. + (mem_regions): New variable. + (num_regions): Likewise. + (pupa_os_area_addr): Likewise. + (pupa_os_area_size): Likewise. + (pupa_lower_mem): Likewise. + (pupa_upper_mem): Likewise. + (add_mem_region): New function. + (compact_mem_regions): Likewise. + (pupa_machine_init): Set PUPA_LOWER_MEM and PUPA_UPPER_MEM to + the size of the conventional memory and that of so-called upper + memory (before the first memory hole). + Instead of adding each found region to free memory, use + add_mem_region and add them after removing overlaps. + Also, add only 1/4 of the upper memory to free memory. The rest + is used for loading OS images. Maybe this is ad hoc, but this + makes it much easier to relocate OS images when booting. + + * kern/rescue.c (pupa_rescue_cmd_module): Removed. + (pupa_enter_rescue_mode): Don't register initrd and module. + + * kern/mm.c: Include pupa/dl.h. + + * kern/main.c: Include pupa/file.h and pupa/device.h. + + * kern/loader.c (pupa_loader_load_module_func): Removed. + (pupa_loader_load_module): Likewise. + + * kern/dl.c (pupa_dl_load): Use the suffix ``.mod'' instead of + ``.o''. + + * include/pupa/i386/pc/loader.h (pupa_linux_prot_size): Declared. + (pupa_linux_tmp_addr): Likewise. + (pupa_linux_real_addr): Likewise. + (pupa_linux_boot_zimage): Likewise. + (pupa_linux_boot_bzimage): Likewise. + + * include/pupa/i386/pc/init.h (pupa_lower_mem): Declared. + (pupa_upper_mem): Likewise. + (pupa_gate_a20): Don't export, because turning off Gate A20 in a + module is too dangerous. + + * include/pupa/loader.h (pupa_os_area_addr): Declared. + (pupa_os_area_size): Likewise. + (pupa_loader_set): Remove the first argument. Loader doesn't + manage modules or initrd any longer. + (pupa_loader_load_module): Removed. + + * conf/i386-pc.rmk (pkgdata_MODULES): Added linux.mod. + (linux_mod_SOURCES): New variable. + (linux_mod_CFLAGS): Likewise. + +2003-01-07 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c (setup): Convert the endianness of + the length of a blocklist correctly. + + * util/i386/pc/biosdisk.c (pupa_util_biosdisk_open) [__linux__]: + Use ioctl only if the OS file is a block device. + (pupa_util_biosdisk_open): Don't use ST.ST_BLOCKS, because it is + not very useful for normal files. + + * kern/main.c (pupa_set_root_dev): New function. + (pupa_load_normal_mode): Likewise. + (pupa_main): Call those above. + + * include/pupa/types.h (pupa_swap_bytes16): Cast the result to + pupa_uint16_t. + + * include/pupa/kernel.h (pupa_enter_normal_mode): Removed. + +2003-01-06 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c: Include pupa/machine/kernel.h. + (setup): Configure the installed partition information and the + dl prefix. + + * loader/i386/pc/chainloader.c (my_mod): New variable. + (pupa_chainloader_unload): New function. + (pupa_rescue_cmd_chainloader): Refer itself. + (PUPA_MOD_INIT): Save its own module in MY_MOD. + + * kern/i386/pc/startup.S (install_partition): Removed. + (version_string): Likewise. + (config_file): Likewise. + (pupa_install_dos_part): New variable. + (pupa_install_bsd_part): Likewise. + (pupa_prefix): Likewise. + (pupa_chainloader_real_boot): Call pupa_dl_unload_all. + + * kern/i386/pc/init.c: Include pupa/machine/kernel.h, pupa/dl.h + and pupa/misc.h. + (make_install_device): New function. + (pupa_machine_init): Set the dl prefix. + + * kern/rescue.c: Include pupa/rescue.h and pupa/dl.h. + (buf): Renamed to ... + (linebuf): ... this. + (pupa_rescue_cmd_prefix): New function. + (pupa_rescue_cmd_insmod): Likewise. + (pupa_rescue_cmd_rmmod): Likewise. + (pupa_rescue_cmd_lsmod): Likewise. + (pupa_enter_rescue_mode): Register new commands: prefix, insmod, + rmmod and lsmod. + + * kern/mm.c (pupa_memalign): If failed even after invalidating + disk caches, unload unneeded modules and retry. + + * kern/misc.c (pupa_memmove): New function. + (pupa_memcpy): Removed. + (pupa_strcpy): New function. + (pupa_itoa): Made static. + + * kern/dl.c (pupa_dl_iterate): New function. + (pupa_dl_ref): Likewise. + (pupa_dl_unref): Likewise. + (pupa_dl_unload): Return if succeeded or not. + (pupa_dl_unload_unneeded): New function. + (pupa_dl_unload_all): Likewise. + (pupa_dl_init): Renamed to ... + (pupa_dl_set_prefix): ... this. + (pupa_dl_get_prefix): New function. + + * include/pupa/i386/pc/kernel.h: Include pupa/types.h. + (PUPA_KERNEL_MACHINE_INSTALL_DOS_PART): New macro. + (PUPA_KERNEL_MACHINE_INSTALL_BSD_PART): Likewise. + (PUPA_KERNEL_MACHINE_PREFIX): Likewise. + (pupa_install_dos_part): Declared. + (pupa_install_bsd_part): Likewise. + (pupa_prefix): Likewise. + (pupa_boot_drive): Likewise. + + * include/pupa/types.h: Fix a typo. + + * include/pupa/misc.h (pupa_memcpy): New macro. Just an alias to + pupa_memmove. + (pupa_memmove): Declared. + (pupa_strcpy): Likewise. + + * include/pupa/dl.h (PUPA_MOD_INIT): Change the prototype. Now + pupa_mod_init takes one argument, its own module. + (pupa_dl_unload_unneeded): Declared. + (pupa_dl_unload_all): Likewise. + (pupa_dl_ref): Likewise. + (pupa_dl_unref): Likewise. + (pupa_dl_iterate): Likewise. + (pupa_dl_init): Renamed to ... + (pupa_dl_set_prefix): ... this. + (pupa_dl_get_prefix): Declared. + + * fs/fat.c [!PUPA_UTIL] (my_mod): New variable. + (pupa_fat_dir) [!PUPA_UTIL]: Prevent the fat module from being + unloaded. + (pupa_fat_open) [!PUPA_UTIL]: Refer itself if succeeded. + (pupa_fat_close) [!PUPA_UTIL]: Unrefer itself. + + * configure.ac (tmp_CFLAGS): Added -Wshadow, -Wpointer-arith, + -Wmissing-prototypes, -Wundef and -Wstrict-prototypes. + +2003-01-03 Yoshinori K. Okuji + + * util/i386/pc/pupa-setup.c (setup): Define the internal + function find_first_partition_start at the top level, because GCC + 3.0.x cannot compile internal functions in deeper scopes + correctly. + (find_root_device): Use lstat instead of stat. + Don't follow symbolic links. + Fix the path-constructing code. + + * util/i386/pc/biosdisk.c [__linux__] (BLKFLSBUF): New macro. + (pupa_util_biosdisk_open) [__linux__]: Get the size of a device + by a BLKGETSIZE ioctl first, because block devices don't fill + the member st_mode of the structure stat on Linux. + [__linux__] (linux_find_partition): Use a temporary buffer + REAL_DEV for the working space. Copy it to DEV before returning. + (open_device) [__linux__]: Call ioctl with BLKFLSBUF to make the + buffer cache consistent. + (get_os_disk) [__linux__]: Use the length 5 instead of 4 for + strncmp. The previous value was merely wrong. + (pupa_util_biosdisk_get_pupa_dev): Use stat instead of lstat. + + * fs/fat.c (pupa_fat_read_data): Shift 4 instead of 12 when the + FAT size is 12. The previous value was merely wrong. + + * kern/main.c (pupa_main): Don't split the starting message from + newlines. + + * kern/term.c (pupa_putchar): Put CR after LF instead of before + LF, because BIOS goes crazy about character attributes in this + case. + +2003-01-03 Yoshinori K. Okuji + + * include/i386/pc/util/biosdisk.h: New file. + * util/i386/pc/biosdisk.c: Likewise. + * util/i386/pc/pupa-setup.c: Likewise. + + * Makefile.in (INCLUDE_DISTFILES): Added + include/pupa/i386/pc/util/biosdisk.h. + (UTIL_DISTFILES): Added biosdisk.c and pupa-setup.c under the + directory util/i386/pc. + (install-local): Added a rule for sbin_UTILITIES. + (uninstall): Likewise. + + * util/i386/pc/pupa-mkimage.c (usage): Fix a typo in the doc. + + * util/misc.c (xrealloc): New function. + (pupa_malloc): Likewise. + (pupa_free): Likewise. + (pupa_realloc): Likewise. + (pupa_stop): Likewise. + (pupa_putchar): Likewise. + + * kern/disk.c (pupa_disk_read): Prevent L from underflowing. + + * include/pupa/util/misc.h (xrealloc): Declared. + + * include/pupa/i386/pc/boot.h (PUPA_BOOT_MACHINE_BPB_START): New + macro. + (PUPA_BOOT_MACHINE_BPBEND): Renamed to ... + (PUPA_BOOT_MACHINE_BPB_END): ... this. + + * include/pupa/fs.h [PUPA_UTIL] (pupa_fat_init): Declared. + [PUPA_UTIL] (pupa_fat_fini): Likewise. + + * fs/fat.c [PUPA_UTIL] (pupa_fat_init): Defined. Maybe a better + way should be implemented. + [PUPA_UTIL] (pupa_fat_fini): Likewise. + + * disk/i386/pc/biosdisk.c (pupa_biosdisk_call_hook): Increase + the size of NAME for safety. + (pupa_biosdisk_iterate): Search hard disks to 0x90 instead of + 0x88. + + * conf/i386-pc.rmk (sbin_UTILITIES): New variable. + (pupa_setup_SOURCES): Likewise. + + * genmk.rb (Utility#rule): Add $(BUILD_CFLAGS) into the rules. + +2002-12-28 Yoshinori K. Okuji + + * kern/i386/pc/startup.S (push_get_mmap_entry): Revert to a + bunch of pushl's from pusha, because this destroys the return + value. + +2002-12-28 Yoshinori K. Okuji + + Use -mrtd and -mregparm=3 to reduce the generated code sizes. + This means that any missing prototypes could be fatal. Also, you + must take care when writing assembly code. See the comments at + the beginning of startup.S, for more details. + + * kern/i386/pc/startup.S (pupa_halt): Modified for the new + compilation mechanism. + (pupa_chainloader_real_boot): Likewise. + (pupa_biosdisk_rw_int13_extensions): Likewise. + (pupa_biosdisk_rw_standard): Likewise. + (pupa_biosdisk_check_int13_extensions): Likewise. + (pupa_biosdisk_get_diskinfo_int13_extensions): Likewise. + (pupa_biosdisk_get_diskinfo_standard): Likewise. + (pupa_get_memsize): Likewise. + (pupa_get_mmap_entry): Likewise. + (pupa_console_putchar): Likewise. + (pupa_console_setcursor): Likewise. + (pupa_getrtsecs): Use pushl instead of push. + + * kern/i386/pc/init.c (pupa_machine_init): Use the scratch + memory instead of the stack for a mmap entry, because some + BIOSes may ignore the maximum size and overflow. + + * conf/i386-pc.rmk (COMMON_CFLAGS): Added -mrtd and -mregparm=3. + + * genmk.rb (PModule#rule): Compile automatically generated + sources with module-specific CFLAGS as well as other sources. + +2002-12-27 Yoshinori K. Okuji + + * configure.ac: Check ld. + Replace CFLAGS and CPPFLAGS with BUILD_CFLAGS and BUILD_CPPFLAGS + respectively, before checking endianness and sizes. + + * Makefile.in (LD): New variable. + +2002-12-27 Yoshinori K. Okuji + + * Makefile.in (BUILD_CC): CC -> BUILD_CC. + +2002-12-27 Yoshinori K. Okuji + + * Changelog: New file. + diff --git a/DISTLIST b/DISTLIST new file mode 100644 index 0000000..a92f733 --- /dev/null +++ b/DISTLIST @@ -0,0 +1,484 @@ +AUTHORS +COPYING +ChangeLog +DISTLIST +INSTALL +NEWS +README +THANKS +TODO +Makefile.in +aclocal.m4 +autogen.sh +config.guess +config.h.in +config.sub +configure +configure.ac +gencmdlist.sh +gendistlist.sh +genfslist.sh +geninit.sh +geninitheader.sh +genkernsyms.sh.in +genmk.rb +genmoddep.awk +genmodsrc.sh +genpartmaplist.sh +gensymlist.sh.in +install-sh +mkinstalldirs +stamp-h.in +boot/i386/pc/boot.S +boot/i386/pc/cdboot.S +boot/i386/pc/diskboot.S +boot/i386/pc/lnxboot.S +boot/i386/pc/pxeboot.S +bus/pci.c +bus/usb/ohci.c +bus/usb/uhci.c +bus/usb/usb.c +bus/usb/usbhub.c +bus/usb/usbtrans.c +commands/blocklist.c +commands/boot.c +commands/cat.c +commands/cmp.c +commands/configfile.c +commands/crc.c +commands/date.c +commands/echo.c +commands/halt.c +commands/hdparm.c +commands/help.c +commands/hexdump.c +commands/loadenv.c +commands/ls.c +commands/lsmmap.c +commands/lspci.c +commands/read.c +commands/reboot.c +commands/search.c +commands/sleep.c +commands/terminal.c +commands/test.c +commands/usbtest.c +commands/videotest.c +commands/i386/cpuid.c +commands/i386/pc/halt.c +commands/i386/pc/play.c +commands/i386/pc/pxecmd.c +commands/i386/pc/vbeinfo.c +commands/i386/pc/vbetest.c +commands/ieee1275/suspend.c +conf/common.mk +conf/common.rmk +conf/i386-coreboot.mk +conf/i386-coreboot.rmk +conf/i386-efi.mk +conf/i386-efi.rmk +conf/i386-ieee1275.mk +conf/i386-ieee1275.rmk +conf/i386-pc-cygwin-img-ld.sc +conf/i386-pc.mk +conf/i386-pc.rmk +conf/i386.mk +conf/i386.rmk +conf/powerpc-ieee1275.mk +conf/powerpc-ieee1275.rmk +conf/sparc64-ieee1275.mk +conf/sparc64-ieee1275.rmk +conf/x86_64-efi.mk +conf/x86_64-efi.rmk +disk/ata.c +disk/ata_pthru.c +disk/dmraid_nvidia.c +disk/fs_uuid.c +disk/host.c +disk/loopback.c +disk/lvm.c +disk/mdraid_linux.c +disk/memdisk.c +disk/raid.c +disk/raid5_recover.c +disk/raid6_recover.c +disk/scsi.c +disk/usbms.c +disk/efi/efidisk.c +disk/i386/pc/biosdisk.c +disk/ieee1275/nand.c +disk/ieee1275/ofdisk.c +docs/fdl.texi +docs/grub.cfg +docs/grub.texi +docs/texinfo.tex +font/font.c +font/font_cmd.c +fs/affs.c +fs/afs.c +fs/cpio.c +fs/ext2.c +fs/fat.c +fs/fshelp.c +fs/hfs.c +fs/hfsplus.c +fs/iso9660.c +fs/jfs.c +fs/minix.c +fs/ntfs.c +fs/ntfscomp.c +fs/reiserfs.c +fs/sfs.c +fs/tar.c +fs/udf.c +fs/ufs.c +fs/xfs.c +fs/i386/pc/pxe.c +hello/hello.c +hook/datehook.c +include/multiboot.h +include/multiboot2.h +include/grub/acorn_filecore.h +include/grub/aout.h +include/grub/arg.h +include/grub/ata.h +include/grub/bitmap.h +include/grub/boot.h +include/grub/bufio.h +include/grub/cache.h +include/grub/device.h +include/grub/disk.h +include/grub/dl.h +include/grub/elf.h +include/grub/elfload.h +include/grub/env.h +include/grub/err.h +include/grub/file.h +include/grub/font.h +include/grub/fs.h +include/grub/fshelp.h +include/grub/gpt_partition.h +include/grub/gzio.h +include/grub/hfs.h +include/grub/kernel.h +include/grub/loader.h +include/grub/lvm.h +include/grub/menu.h +include/grub/menu_viewer.h +include/grub/misc.h +include/grub/mm.h +include/grub/multiboot.h +include/grub/multiboot2.h +include/grub/multiboot_loader.h +include/grub/net.h +include/grub/normal.h +include/grub/ntfs.h +include/grub/parser.h +include/grub/partition.h +include/grub/pc_partition.h +include/grub/pci.h +include/grub/raid.h +include/grub/rescue.h +include/grub/script.h +include/grub/scsi.h +include/grub/scsicmd.h +include/grub/setjmp.h +include/grub/symbol.h +include/grub/term.h +include/grub/terminfo.h +include/grub/time.h +include/grub/tparm.h +include/grub/types.h +include/grub/usb.h +include/grub/usbdesc.h +include/grub/usbtrans.h +include/grub/video.h +include/grub/efi/api.h +include/grub/efi/chainloader.h +include/grub/efi/console.h +include/grub/efi/console_control.h +include/grub/efi/disk.h +include/grub/efi/efi.h +include/grub/efi/pe32.h +include/grub/efi/time.h +include/grub/efi/uga_draw.h +include/grub/i386/at_keyboard.h +include/grub/i386/bsd.h +include/grub/i386/cmos.h +include/grub/i386/halt.h +include/grub/i386/io.h +include/grub/i386/kernel.h +include/grub/i386/linux.h +include/grub/i386/loader.h +include/grub/i386/pci.h +include/grub/i386/pit.h +include/grub/i386/reboot.h +include/grub/i386/setjmp.h +include/grub/i386/time.h +include/grub/i386/tsc.h +include/grub/i386/types.h +include/grub/i386/vga_common.h +include/grub/i386/coreboot/boot.h +include/grub/i386/coreboot/console.h +include/grub/i386/coreboot/init.h +include/grub/i386/coreboot/kernel.h +include/grub/i386/coreboot/loader.h +include/grub/i386/coreboot/machine.h +include/grub/i386/coreboot/memory.h +include/grub/i386/coreboot/serial.h +include/grub/i386/coreboot/time.h +include/grub/i386/efi/kernel.h +include/grub/i386/efi/loader.h +include/grub/i386/efi/machine.h +include/grub/i386/efi/time.h +include/grub/i386/ieee1275/console.h +include/grub/i386/ieee1275/ieee1275.h +include/grub/i386/ieee1275/kernel.h +include/grub/i386/ieee1275/loader.h +include/grub/i386/ieee1275/machine.h +include/grub/i386/ieee1275/memory.h +include/grub/i386/ieee1275/serial.h +include/grub/i386/ieee1275/time.h +include/grub/i386/pc/biosdisk.h +include/grub/i386/pc/boot.h +include/grub/i386/pc/chainloader.h +include/grub/i386/pc/console.h +include/grub/i386/pc/init.h +include/grub/i386/pc/kernel.h +include/grub/i386/pc/loader.h +include/grub/i386/pc/machine.h +include/grub/i386/pc/memory.h +include/grub/i386/pc/pxe.h +include/grub/i386/pc/serial.h +include/grub/i386/pc/time.h +include/grub/i386/pc/vbe.h +include/grub/i386/pc/vbeblit.h +include/grub/i386/pc/vbefill.h +include/grub/i386/pc/vbeutil.h +include/grub/i386/pc/vga.h +include/grub/ieee1275/ieee1275.h +include/grub/ieee1275/ofdisk.h +include/grub/lib/LzFind.h +include/grub/lib/LzHash.h +include/grub/lib/LzmaDec.h +include/grub/lib/LzmaEnc.h +include/grub/lib/LzmaTypes.h +include/grub/lib/crc.h +include/grub/lib/datetime.h +include/grub/lib/envblk.h +include/grub/lib/hexdump.h +include/grub/powerpc/kernel.h +include/grub/powerpc/libgcc.h +include/grub/powerpc/setjmp.h +include/grub/powerpc/time.h +include/grub/powerpc/types.h +include/grub/powerpc/ieee1275/biosdisk.h +include/grub/powerpc/ieee1275/console.h +include/grub/powerpc/ieee1275/ieee1275.h +include/grub/powerpc/ieee1275/kernel.h +include/grub/powerpc/ieee1275/loader.h +include/grub/powerpc/ieee1275/machine.h +include/grub/powerpc/ieee1275/memory.h +include/grub/powerpc/ieee1275/time.h +include/grub/powerpc/ieee1275/util/biosdisk.h +include/grub/sparc64/libgcc.h +include/grub/sparc64/setjmp.h +include/grub/sparc64/time.h +include/grub/sparc64/types.h +include/grub/sparc64/ieee1275/console.h +include/grub/sparc64/ieee1275/ieee1275.h +include/grub/sparc64/ieee1275/kernel.h +include/grub/sparc64/ieee1275/machine.h +include/grub/sparc64/ieee1275/time.h +include/grub/util/getroot.h +include/grub/util/hostdisk.h +include/grub/util/lvm.h +include/grub/util/misc.h +include/grub/util/raid.h +include/grub/util/resolve.h +include/grub/x86_64/kernel.h +include/grub/x86_64/linux.h +include/grub/x86_64/pci.h +include/grub/x86_64/setjmp.h +include/grub/x86_64/time.h +include/grub/x86_64/types.h +include/grub/x86_64/efi/kernel.h +include/grub/x86_64/efi/loader.h +include/grub/x86_64/efi/machine.h +include/grub/x86_64/efi/time.h +io/bufio.c +io/gzio.c +kern/device.c +kern/disk.c +kern/dl.c +kern/elf.c +kern/env.c +kern/err.c +kern/file.c +kern/fs.c +kern/loader.c +kern/main.c +kern/misc.c +kern/mm.c +kern/parser.c +kern/partition.c +kern/rescue.c +kern/term.c +kern/time.c +kern/efi/efi.c +kern/efi/init.c +kern/efi/mm.c +kern/generic/millisleep.c +kern/generic/rtc_get_time_ms.c +kern/i386/dl.c +kern/i386/halt.c +kern/i386/loader.S +kern/i386/multiboot_mmap.c +kern/i386/pit.c +kern/i386/realmode.S +kern/i386/reboot.c +kern/i386/tsc.c +kern/i386/coreboot/init.c +kern/i386/coreboot/mmap.c +kern/i386/coreboot/startup.S +kern/i386/efi/init.c +kern/i386/efi/startup.S +kern/i386/ieee1275/init.c +kern/i386/ieee1275/startup.S +kern/i386/pc/init.c +kern/i386/pc/lzma_decode.S +kern/i386/pc/lzo1x.S +kern/i386/pc/mmap.c +kern/i386/pc/startup.S +kern/ieee1275/cmain.c +kern/ieee1275/ieee1275.c +kern/ieee1275/init.c +kern/ieee1275/mmap.c +kern/ieee1275/openfw.c +kern/powerpc/cache.S +kern/powerpc/dl.c +kern/powerpc/ieee1275/startup.S +kern/sparc64/cache.S +kern/sparc64/dl.c +kern/sparc64/ieee1275/init.c +kern/sparc64/ieee1275/openfw.c +kern/x86_64/dl.c +kern/x86_64/efi/callwrap.S +kern/x86_64/efi/startup.S +lib/LzFind.c +lib/LzmaDec.c +lib/LzmaEnc.c +lib/crc.c +lib/datetime.c +lib/envblk.c +lib/hexdump.c +lib/efi/datetime.c +lib/i386/datetime.c +loader/aout.c +loader/linux_normal.c +loader/multiboot2.c +loader/multiboot_loader.c +loader/multiboot_loader_normal.c +loader/efi/appleloader.c +loader/efi/chainloader.c +loader/efi/chainloader_normal.c +loader/i386/bsd.c +loader/i386/bsd_normal.c +loader/i386/linux.c +loader/i386/efi/linux.c +loader/i386/ieee1275/linux.c +loader/i386/pc/chainloader.c +loader/i386/pc/chainloader_normal.c +loader/i386/pc/linux.c +loader/i386/pc/multiboot.c +loader/i386/pc/multiboot2.c +loader/i386/pc/multiboot_normal.c +loader/ieee1275/multiboot2.c +loader/powerpc/ieee1275/linux.c +loader/powerpc/ieee1275/linux_normal.c +normal/arg.c +normal/cmdline.c +normal/color.c +normal/command.c +normal/completion.c +normal/execute.c +normal/function.c +normal/lexer.c +normal/main.c +normal/menu.c +normal/menu_entry.c +normal/menu_text.c +normal/menu_viewer.c +normal/misc.c +normal/parser.y +normal/script.c +normal/i386/setjmp.S +normal/powerpc/setjmp.S +normal/sparc64/setjmp.S +normal/x86_64/setjmp.S +partmap/acorn.c +partmap/amiga.c +partmap/apple.c +partmap/gpt.c +partmap/pc.c +partmap/sun.c +term/gfxterm.c +term/terminfo.c +term/tparm.c +term/usb_keyboard.c +term/efi/console.c +term/i386/vga_common.c +term/i386/pc/at_keyboard.c +term/i386/pc/console.c +term/i386/pc/serial.c +term/i386/pc/vesafb.c +term/i386/pc/vga.c +term/i386/pc/vga_text.c +term/ieee1275/ofconsole.c +util/console.c +util/getroot.c +util/grub-editenv.c +util/grub-emu.c +util/grub-fstest.c +util/grub-mkconfig.in +util/grub-mkconfig_lib.in +util/grub-mkdevicemap.c +util/grub-mkfont.c +util/grub-pe2elf.c +util/grub-probe.c +util/hostdisk.c +util/hostfs.c +util/lvm.c +util/misc.c +util/raid.c +util/resolve.c +util/update-grub_lib.in +util/usb.c +util/elf/grub-mkimage.c +util/grub.d/00_header.in +util/grub.d/10_freebsd.in +util/grub.d/10_hurd.in +util/grub.d/10_linux.in +util/grub.d/10_windows.in +util/grub.d/30_os-prober.in +util/grub.d/40_custom.in +util/grub.d/README +util/i386/efi/grub-install.in +util/i386/efi/grub-mkimage.c +util/i386/pc/grub-install.in +util/i386/pc/grub-mkimage.c +util/i386/pc/grub-mkrescue.in +util/i386/pc/grub-setup.c +util/i386/pc/misc.c +util/ieee1275/grub-install.in +util/powerpc/ieee1275/grub-mkrescue.in +util/powerpc/ieee1275/misc.c +video/bitmap.c +video/video.c +video/i386/pc/vbe.c +video/i386/pc/vbeblit.c +video/i386/pc/vbefill.c +video/i386/pc/vbeutil.c +video/readers/jpeg.c +video/readers/png.c +video/readers/tga.c diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e2b7c00 --- /dev/null +++ b/INSTALL @@ -0,0 +1,159 @@ +-*- Text -*- + +This is the GRUB. Welcome. + +This file contains instructions for compiling and installing the GRUB. + +The Requirements +================ + +GRUB depends on some software packages installed into your system. If +you don't have any of them, please obtain and install them before +configuring the GRUB. + +* GCC 2.95 or later +* GNU Make +* GNU Bison +* GNU binutils 2.9.1.0.23 or later +* Other standard GNU/Unix tools +* LZO 1.02 or later (optional) + +If you'd like to develop GRUB, these below are also required. + +* Ruby 1.6 or later +* Autoconf 2.59 or later + +Configuring the GRUB +==================== + +The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a +file `config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + +If you need to do unusual things to compile the package, please try to +figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + +The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + + +Building the GRUB +================= + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and + type `./configure' to configure the package for your system. If + you're using `csh' on an old version of System V, you might need + to type `sh ./configure' instead to prevent `csh' from trying to + execute `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. `cd' to the directory where you want the object files +and executables to go and run the `configure' script. `configure' +automatically checks for the source code in the directory that +`configure' is in and in `..'. + + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix by giving `configure' the option `--prefix=PATH'. + +You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If +you give `configure' the option `--exec-prefix=PATH', the package will +use PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + +In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for +particular kinds of files. Run `configure --help' for a list of the +directories you can set and what kinds of files go in them. + +If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' +the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Please note, however, that the GRUB knows where it is located in the +filesystem. If you have installed it in an unusual location, the +system might not work properly, or at all. The chief utility of these +options for the GRUB is to allow you to "install" in some alternate +location, and then copy these to the actual root filesystem later. + + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..44dc577 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,396 @@ +# -*- makefile -*- +# +# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2009,2008 Free Software Foundation, Inc. +# +# This Makefile.in is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +### The configure script will replace these variables. + +SHELL = /bin/sh + +@SET_MAKE@ + +transform = @program_transform_name@ + +srcdir = @srcdir@ +builddir = @builddir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datarootdir = @datarootdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +pkgdatadir = $(datadir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'` +pkglibdir = $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed '$(transform)'` + +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +host_os = @host_os@ +host_cpu = @host_cpu@ + +target_cpu = @target_cpu@ +platform = @platform@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ + +mkinstalldirs = $(srcdir)/mkinstalldirs + +CC = @CC@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ +CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include -Wall -W \ + -DGRUB_LIBDIR=\"$(pkglibdir)\" +TARGET_CC = @TARGET_CC@ +TARGET_CFLAGS = @TARGET_CFLAGS@ +TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/include \ + -Wall -W +TARGET_LDFLAGS = @TARGET_LDFLAGS@ +TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ +TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@ +TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ +MODULE_LDFLAGS = @MODULE_LDFLAGS@ +EXEEXT = @EXEEXT@ +OBJCOPY = @OBJCOPY@ +STRIP = @STRIP@ +NM = @NM@ +RUBY = @RUBY@ +HELP2MAN = @HELP2MAN@ +ifeq (, $(HELP2MAN)) +HELP2MAN = true +else +HELP2MAN := LANG=C $(HELP2MAN) --no-info --source=FSF +endif +AWK = @AWK@ +LIBCURSES = @LIBCURSES@ +LIBLZO = @LIBLZO@ +YACC = @YACC@ +UNIFONT_BDF = @UNIFONT_BDF@ + +# Options. +enable_grub_emu = @enable_grub_emu@ +enable_grub_emu_usb = @enable_grub_emu_usb@ +enable_grub_fstest = @enable_grub_fstest@ +enable_grub_pe2elf = @enable_grub_pe2elf@ +enable_lzo = @enable_lzo@ +enable_grub_mkfont = @enable_grub_mkfont@ +freetype_cflags = @freetype_cflags@ +freetype_libs = @freetype_libs@ + +### General variables. + +RMKFILES = $(addprefix conf/,common.rmk i386-coreboot.rmk i386-efi.rmk \ + i386-ieee1275.rmk i386-pc.rmk i386.rmk powerpc-ieee1275.rmk \ + sparc64-ieee1275.rmk x86_64-efi.rmk) + +MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES)) + +PKGLIB = $(pkglib_IMAGES) $(pkglib_MODULES) $(pkglib_PROGRAMS) \ + $(pkglib_DATA) $(lib_DATA) $(pkglib_BUILDDIR) +PKGDATA = $(pkgdata_DATA) $(pkgdata_SRCDIR) +PROGRAMS = $(bin_UTILITIES) $(sbin_UTILITIES) +SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS) + +CLEANFILES = +MOSTLYCLEANFILES = +DISTCLEANFILES = config.status config.cache config.log config.h \ + Makefile stamp-h include/grub/cpu include/grub/machine \ + gensymlist.sh genkernsyms.sh build_env.mk +MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES)) + +# The default target. +all: all-local + +### Include an arch-specific Makefile. +$(addprefix $(srcdir)/,$(MKFILES)): %.mk: %.rmk genmk.rb + if test "x$(RUBY)" = x; then \ + touch $@; \ + else \ + $(RUBY) $(srcdir)/genmk.rb < $< > $@; \ + fi + +include $(srcdir)/conf/$(target_cpu)-$(platform).mk + +### General targets. + +CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) +pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst +moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk + cat $(DEFSYMFILES) /dev/null \ + | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \ + || (rm -f $@; exit 1) + +command.lst: $(COMMANDFILES) + cat $^ /dev/null | sort > $@ + +fs.lst: $(FSFILES) + cat $^ /dev/null | sort > $@ + +partmap.lst: $(PARTMAPFILES) + cat $^ /dev/null | sort > $@ + +ifeq (, $(UNIFONT_BDF)) +else + +ifeq ($(enable_grub_mkfont),yes) + +pkgdata_DATA += unicode.pf2 ascii.pf2 + +# Arrows and lines are needed to draw the menu, so we always include them +UNICODE_ARROWS=0x2190-0x2193 +UNICODE_LINES=0x2501-0x251B + +unicode.pf2: $(UNIFONT_BDF) grub-mkfont + $(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF) + +ascii.pf2: $(UNIFONT_BDF) grub-mkfont + $(builddir)/grub-mkfont -o $@ $(UNIFONT_BDF) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) +endif +endif + +# Used for building modules externally +pkglib_BUILDDIR += build_env.mk +build_env.mk: Makefile + (\ + echo "TARGET_CC=$(TARGET_CC)" ; \ + echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir)" ; \ + echo "STRIP=$(STRIP)" ; \ + echo "COMMON_ASFLAGS=$(COMMON_ASFLAGS)" ; \ + echo "COMMON_CFLAGS=$(COMMON_CFLAGS)" ; \ + echo "COMMON_LDFLAGS=$(COMMON_LDFLAGS)"\ + ) > $@ +pkglib_BUILDDIR += config.h grub_script.tab.h +pkgdata_SRCDIR += genmodsrc.sh genmk.rb +include_DATA += $(shell find $(srcdir)/include -name \*.h | sed -e "s,^$(srcdir)/,,g") include/grub/cpu + +all-local: $(PROGRAMS) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(MKFILES) + +install: install-local + +install-local: all + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + @list='$(PKGLIB)'; \ + for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkglibdir)/$$dest; \ + done + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_DATA)'; \ + for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,include/,,'`"; \ + destdir="`echo $$dest | sed 's,\(^\|/\)[^/]*$$,,g'`"; \ + $(mkinstalldirs) $(DESTDIR)$(includedir)/$$destdir; \ + if test -f "$$dir$$file"; then \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(includedir)/$$dest; \ + elif test -L "$$dir$$file"; then \ + cp -d $$dir$$file $(DESTDIR)$(includedir)/$$dest; \ + fi; \ + done + $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) + @list='$(PKGDATA)'; \ + for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkgdatadir)/$$dest; \ + done + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1 + @list='$(bin_UTILITIES)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ + $(HELP2MAN) --section=1 $(builddir)/$$file > $(DESTDIR)$(mandir)/man1/$$dest.1; \ + done + $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 + @list='$(sbin_UTILITIES)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ + $(HELP2MAN) --section=8 $(builddir)/$$file > $(DESTDIR)$(mandir)/man8/$$dest.8; \ + done + @list='$(bin_SCRIPTS)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ + $(HELP2MAN) --section=1 $(builddir)/$$file > $(DESTDIR)$(mandir)/man1/$$dest.1; \ + done + @list='$(sbin_SCRIPTS)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ + $(HELP2MAN) --section=8 $(builddir)/$$file > $(DESTDIR)$(mandir)/man8/$$dest.8; \ + done + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d + @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \ + done + @list='$(grub-mkconfig_DATA)'; for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \ + done + $(mkinstalldirs) $(DESTDIR)$(libdir)/grub + @list='$(lib_DATA)'; \ + for file in $$list; do \ + if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(libdir)/grub/$$dest; \ + done + +install-strip: + $(MAKE) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" install + +uninstall: + @list='$(PKGLIB)'; \ + for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + rm -f $(DESTDIR)$(pkglibdir)/$$dest; \ + done + @list='$(PKGDATA)'; \ + for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,'`"; \ + rm -f $(DESTDIR)$(pkgdatadir)/$$dest; \ + done + @list='$(bin_UTILITIES) $(bin_SCRIPTS)'; for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + rm -f $(DESTDIR)$(bindir)/$$dest; \ + done + @list='$(sbin_UTILITIES) $(sbin_SCRIPTS)'; for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + rm -f $(DESTDIR)$(sbindir)/$$dest; \ + done + @list='$(grub-mkconfig_SCRIPTS) $(grub-mkconfig_DATA)'; for file in $$list; do \ + dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ + rm -f $(DESTDIR)$(sysconfdir)/grub.d/$$dest; \ + done + +clean: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +mostlyclean: clean + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +distclean: mostlyclean + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + -rm -rf $(srcdir)/autom4te.cache + +maintainer-clean: distclean + -test -z "$(MAINTAINER_CLEANFILES)" || rm -f $(MAINTAINER_CLEANFILES) + +info: + +dvi: + +distdir=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION) + +DISTLIST: gendistlist.sh + sh $(srcdir)/gendistlist.sh > $(srcdir)/DISTLIST + +distdir: DISTLIST + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + $(mkinstalldirs) $(distdir) + for i in `cat $(srcdir)/DISTLIST`; do \ + dir=`echo "$$i" | sed 's:/[^/]*$$::'`; \ + if test -d $(srcdir)/$$dir; then \ + $(mkinstalldirs) $(distdir)/$$dir; \ + fi; \ + cp -p $(srcdir)/$$i $(distdir)/$$i || exit 1; \ + done + chmod -R a+r $(distdir) + +GZIP_ENV = --best + +dist: distdir + tar chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + +distcheck: dist + -chmod -R a+w $(distdir) >/dev/null 2>&1; rm -rf $(distdir) + GZIP=$(GZIP_ENV) gzip -cd $(distdir).tar.gz | tar xf - + chmod -R a-w $(distdir) + chmod a+w $(distdir) + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + chmod a-w $(distdir) + dc_instdir=`CDPATH=: && cd $(distdir)/=inst && pwd` \ + && cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_instdir \ + && $(MAKE) all dvi check install && $(MAKE) uninstall \ + && (test `find $$dc_instdir -type f -print | wc -l` -le 1 \ + || (echo "Error: files left after uninstall" 1>&2; \ + exit 1)) \ + && $(MAKE) dist && $(MAKE) distclean \ + && rm -f $(distdir).tar.gz \ + && (test `find . -type f -print | wc -l` -eq 0 \ + || (echo "Error: files left after distclean" 1>&2; \ + exit 1)) + -chmod -R a+w $(distdir) > /dev/null 2>&1; rm -rf $(distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' + +check: + +.SUFFIX: +.SUFFIX: .c .o .S .d + +# Regenerate configure and Makefile automatically. +$(srcdir)/configure: configure.ac aclocal.m4 + cd $(srcdir) && autoconf + +$(srcdir)/config.h.in: stamp-h.in +$(srcdir)/stamp-h.in: configure.ac aclocal.m4 + cd $(srcdir) && autoheader + echo timestamp > $(srcdir)/stamp-h.in + +config.h: stamp-h +stamp-h: config.h.in config.status + ./config.status + +Makefile: Makefile.in config.status + ./config.status + +config.status: configure + ./config.status --recheck + +gensymlist.sh: gensymlist.sh.in config.status + ./config.status + +genkernsyms.sh: genkernsyms.sh.in config.status + ./config.status + +.PHONY: all install install-strip uninstall clean mostlyclean distclean +.PHONY: maintainer-clean info dvi dist check + +# Prevent an overflow. +.NOEXPORT: + +.DELETE_ON_ERROR: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e223cdb --- /dev/null +++ b/NEWS @@ -0,0 +1,223 @@ +New in 1.97 - : + +* update-grub is renamed to grub-mkconfig. + +* When booting from PXE, PXE can be used to load files. + +* High resolution timer support. + +* Image loaders now support IO buffering. + +* Add `crc' command. + +* Add Cygwin support. + +* Add grub-pe2elf to convert PE modules to ELF modules. + +* Add x86_64 EFI support. + +* Add support for LZMA compression. + +* Support for saving the environment from and loading the environment + from a file. + +* Allow the UUID to be used as device name. + +* The `search' command can use UUIDs now. + +* Add support for IEEE 1275 on i386. + +* Create partmap.lst and use it to automatically load partition map + modules. + +* grub-mkconfig supports os-prober to add operating systems to the + boot menu. + +* The ATA driver supports filesystems bigger than 2TB. + +* Add support for the UDF, AFS and EXT4 filesystems. + +* The ISO9660 filesystem supports the Joliet extension + +* Add aout and BSD kernel loaders. + +* Add new command `sleep'. + +* Support for direct access to AT keyboards. + +* New utility `grub-fstest'. + +New in 1.96 - 2008-02-03: + +* The license term is changed to GNU General Public License Version 3. + +* grub-emu is made optional. Now you have to use + `--enable-grub-emu' to enable it. + +* Add Multiboot2 support. + +* grub-emu can access the host filesystem now. + +* Add support for the NTFS, cpio/tar and Reiserfs filesystems. + +* Add support for ATA/ATAPI. + +* Add update-grub script to generate grub.cfg. + +* Add grub-mkrescue script to generate floppy or ElTorito images + (i386-pc only). + +* Add support for background images in gfxterm (background_image command). + +* Add support for detection of 64-bit support in CPU (cpuid command). + +* GPT is now enabled in i386-pc target. + +* Add grub-install for EFI. + +* Ported to the following new platforms: Efika, coreboot (a.k.a. LinuxBIOS), + OLPC XO. + +* Add support for colored menu (menu_color_normal and menu_color_highlight + variables). + +* Fix support for loading Linux zImages (such as memtest86). + +New in 1.95 - 2006-10-15: + +* Number partitions from 1 instead of 0. For instance, the first + partition of "hd0" is now "hd0,1" but not "hd0,0". + +* grub-probefs is renamed to grub-probe, and supports printing a + guessed OS device name and a GRUB drive name. + +* RAID and LVM support is added. + +* New command, echo. + +* The disk API is changed to support 64-bit addressing. + +* A TGA loader is added for the video API. + +New in 1.94 - 2006-06-04: + +* Fix several serious bugs in HFS+. + +* Add experimental EFI support. Chainloading and Linux loading are + supported at the moment. + +* Add a new command "blocklist" to show a block list. + +* Use --with-platform to specify a boot environment. For now, efi, + ieee1275 and pc are supported. + +* Use the filename "kernel.elf" instead of "grubof" on ieee1275. + +* Install GRUB into pkglibdir instead of pkgdatadir. + +* Support environmental variables. You can export variables by the + command "export". + +* Remove the commands "default" and "timeout". They are now variables. + +* Add the commands "source" and "." to include a file. + +* Implement experimental Video API and a new terminal "gfxterm" based + on the Video API. + + +New in 1.93 - 2006-03-10: + +* Add support for the HFS+ wrapper. + +* Major improvements to scripting support. + +* Menu entries are now scriptable. + + +New in 1.92 - 2005-12-25: + +* Add support for GPT partition table format. + +* Add a new command "play" to play an audio file on PC. + +* Add support for Linux/ADFS partition table format. + +* Add support for BASH-like scripting. + +* Add support for Apple HFS+ filesystems. + + +New in 1.91 - 2005-10-15: + +* Add support for LZO version 2. + +* Support completion in the entry editor. + +* Add VBE support. + +* New commands, "search", "vbetest" and "vbeinfo". + +* The option BOOT_IMAGE is passed to Linux. + +* Add support for automatic decompression for gzip. + +* Add support for terminfo and serial. + +* Add support for x86_64. + +* GRUB itself is a Multiboot-compliant kernel. + +* Add new filesystems: XFS, SFS, and AFFS. + + +New in 1.90 - 2005-08-07: + +* Rename the project name PUPA to GRUB. Now this version is the + developmental version of GRUB officially. + +* The GRUB emulator ``grub-emu'' is added. + +* Add support for newworld Mac. This should work with other + PowerPC-based machines as well, if they use IEEE 1275 + (Open Firmware). + +* Too many changes to describe. Look at ChangeLog for more details. + + +New in 0.7: + +* Problems in cross-compiling PUPA are fixed. + +* Use -mrtd and -mregparm=3 to reduce the generated code sizes. This + means that any missing prototypes could be fatal. Also, you must take + care when writing assembly code. See the comments at the beginning of + startup.S, for more details. + +* New utility, ``pupa-setup''. This sets up PUPA to make it bootable + from a real disk. + +* New commands, "prefix", "insmod", "rmmod" and "lsmod" are added into + the rescue mode to manipulate PUPA modules. + +* Linux support is added. Initrd is not support yet. + +* Reduce the size of a core image significantly by compressing a large + part of the core image and decompressing itself at boot time. The + currently used algorithm is LZO (more precisely, LZO1X-999). So you + have to install LZO to build PUPA. See + , for more information. + + +New in 0.6 - 2002-12-27, Yoshinori K. Okuji: + +* The chainloader and the FAT filesystem are modularized. + +* The structure of the source tree is a bit changed. + +* Support for building loadable modules is added. + +* Some generic parts of pupa-mkimage are segregated. + +* Some documentation files are added, according to the GNU Coding + Standards. diff --git a/README b/README new file mode 100644 index 0000000..b6c7fd6 --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +This is GRUB 2, the second version of the GRand Unified Bootloader. +GRUB 2 is rewritten from scratch to make GNU GRUB cleaner, safer, more +robust, more powerful, and more portable. + +See the file NEWS for a description of recent changes to GRUB 2. + +See the file INSTALL for instructions on how to build and install the +GRUB 2 data and program files. + +Please visit the official web page of GRUB 2, for more information. +The URL is . + +For now, there is not much documentation yet. Please look at the GRUB +Wiki for testing procedures. diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..445bb6f --- /dev/null +++ b/THANKS @@ -0,0 +1,37 @@ +GRUB 2 would not be what it is today without the invaluable help of +everybody who was kind enough to spend time testing it and reporting +bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, add new features, and +generally assist in the GRUB 2 maintainership process: + +Andrey Shuvikov +Bibo Mao +Guillem Jover +Harley D. Eades III +Hitoshi Ozeki +Hollis Blanchard +Jeroen Dekkers +Johan Rydberg +Marco Gerards +Michael Guntsche +NIIBE Yutaka +Omniflux +Robert Bihlmeyer +Roger Leigh +Ruslan Nikolaev +Timothy Baldwin +Tomas Ebenlendr +Tristan Gingold +Tsuneyoshi Yasuo +Vesa Jaaskelainen +Vincent Guffens +Vincent Pelletier +Vladimir Serbinenko + +Also, we thank the projects GNU Automake and LZO. Some code +was stolen from them. + +This project was supported by Information-technology Promotion Agency, +Japan. diff --git a/TODO b/TODO new file mode 100644 index 0000000..6ec1521 --- /dev/null +++ b/TODO @@ -0,0 +1,13 @@ + +Before working on improving GRUB, it's very important that you +make contact with the core GRUB developers. Things herein might be +slightly out of date or otherwise not easy to understand at first +glance. So write to first. + +For bug tracking, refer to: + + http://savannah.gnu.org/bugs/?group=grub + +Our wiki also lists some areas that need work: + + http://grub.enbug.org/ diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..1dd5ffb --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,450 @@ +dnl Check whether target compiler is working +AC_DEFUN(grub_PROG_TARGET_CC, +[AC_MSG_CHECKING([whether target compiler is working]) +AC_CACHE_VAL(grub_cv_prog_target_cc, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_prog_target_cc=yes], + [grub_cv_prog_target_cc=no]) +]) +AC_MSG_RESULT([$grub_cv_prog_target_cc]) + +if test "x$grub_cv_prog_target_cc" = xno; then + AC_MSG_ERROR([cannot compile for the target]) +fi +]) + + +dnl grub_ASM_USCORE checks if C symbols get an underscore after +dnl compiling to assembler. +dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by +dnl Erich Boleyn and modified by Yoshinori K. Okuji. +AC_DEFUN(grub_ASM_USCORE, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if C symbols get an underscore after compilation]) +AC_CACHE_VAL(grub_cv_asm_uscore, +[cat > conftest.c <<\EOF +int +func (int *list) +{ + *list = 0; + return *list; +} +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then + true +else + AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) +fi + +if grep _func conftest.s >/dev/null 2>&1; then + grub_cv_asm_uscore=yes +else + grub_cv_asm_uscore=no +fi + +rm -f conftest*]) + +if test "x$grub_cv_asm_uscore" = xyes; then + AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore, + [Define if C symbols get an underscore after compilation]) +fi + +AC_MSG_RESULT([$grub_cv_asm_uscore]) +]) + + +dnl Some versions of `objcopy -O binary' vary their output depending +dnl on the link address. +AC_DEFUN(grub_PROG_OBJCOPY_ABSOLUTE, +[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses]) +AC_CACHE_VAL(grub_cv_prog_objcopy_absolute, +[cat > conftest.c <<\EOF +void +cmain (void) +{ + *((int *) 0x1000) = 2; +} +EOF + +if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then : +else + AC_MSG_ERROR([${CC-cc} cannot compile C source code]) +fi +grub_cv_prog_objcopy_absolute=yes +for link_addr in 2000 8000 7C00; do + if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : + else + AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) + fi + if AC_TRY_COMMAND([${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest]); then : + else + AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files]) + fi + if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then + mv -f conftest conftest.old + else + grub_cv_prog_objcopy_absolute=no + break + fi +done +rm -f conftest*]) +AC_MSG_RESULT([$grub_cv_prog_objcopy_absolute]) + +if test "x$grub_cv_prog_objcopy_absolute" = xno; then + AC_MSG_ERROR([GRUB requires a working absolute objcopy; upgrade your binutils]) +fi +]) + + +dnl Supply --build-id=none to ld if building modules. +dnl This suppresses warnings from ld on some systems +AC_DEFUN(grub_PROG_LD_BUILD_ID_NONE, +[AC_MSG_CHECKING([whether linker accepts --build-id=none]) +AC_CACHE_VAL(grub_cv_prog_ld_build_id_none, +[save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS -Wl,--build-id=none" +AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_prog_ld_build_id_none=yes], + [grub_cv_prog_ld_build_id_none=no]) +LDFLAGS="$save_LDFLAGS" +]) +AC_MSG_RESULT([$grub_cv_prog_ld_build_id_none]) + +if test "x$grub_cv_prog_ld_build_id_none" = xyes; then + MODULE_LDFLAGS="$MODULE_LDFLAGS -Wl,--build-id=none" +fi +]) + + +dnl Mass confusion! +dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit +dnl instructions, but implicitly insert addr32 and data32 bytes so +dnl that the code works in real mode''. +dnl +dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit +dnl instructions,'' which seems right. This requires the programmer +dnl to explicitly insert addr32 and data32 instructions when they want +dnl them. +dnl +dnl We only support the newer versions, because the old versions cause +dnl major pain, by requiring manual assembly to get 16-bit instructions into +dnl asm files. +AC_DEFUN(grub_I386_ASM_ADDR32, +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([grub_I386_ASM_PREFIX_REQUIREMENT]) +AC_MSG_CHECKING([for .code16 addr32 assembler support]) +AC_CACHE_VAL(grub_cv_i386_asm_addr32, +[cat > conftest.s.in <<\EOF + .code16 +l1: @ADDR32@ movb %al, l1 +EOF + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s +else + sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s +fi + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_addr32=yes +else + grub_cv_i386_asm_addr32=no +fi + +rm -f conftest*]) + +AC_MSG_RESULT([$grub_cv_i386_asm_addr32])]) + + +dnl Later versions of GAS requires that addr32 and data32 prefixes +dnl appear in the same lines as the instructions they modify, while +dnl earlier versions requires that they appear in separate lines. +AC_DEFUN(grub_I386_ASM_PREFIX_REQUIREMENT, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether addr32 must be in the same line as the instruction]) +AC_CACHE_VAL(grub_cv_i386_asm_prefix_requirement, +[cat > conftest.s <<\EOF + .code16 +l1: addr32 movb %al, l1 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_prefix_requirement=yes +else + grub_cv_i386_asm_prefix_requirement=no +fi + +rm -f conftest*]) + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + grub_tmp_addr32="addr32" + grub_tmp_data32="data32" +else + grub_tmp_addr32="addr32;" + grub_tmp_data32="data32;" +fi + +AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32, + [Define it to \"addr32\" or \"addr32;\" to make GAS happy]) +AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32, + [Define it to \"data32\" or \"data32;\" to make GAS happy]) + +AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])]) + + +dnl Older versions of GAS require that absolute indirect calls/jumps are +dnl not prefixed with `*', while later versions warn if not prefixed. +AC_DEFUN(grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING(dnl +[whether an absolute indirect call/jump must not be prefixed with an asterisk]) +AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk, +[cat > conftest.s <<\EOF + lcall *(offset) +offset: + .long 0 + .word 0 +EOF + +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then + grub_cv_i386_asm_absolute_without_asterisk=no +else + grub_cv_i386_asm_absolute_without_asterisk=yes +fi + +rm -f conftest*]) + +if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then + AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1, + [Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk]) +fi + +AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) + + +dnl Check what symbol is defined as a start symbol. +dnl Written by Yoshinori K. Okuji. +AC_DEFUN(grub_CHECK_START_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if start is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_start_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl start")]])], + [grub_cv_check_start_symbol=yes], + [grub_cv_check_start_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_start_symbol]) + +AC_MSG_CHECKING([if _start is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_uscore_start_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl _start")]])], + [grub_cv_check_uscore_start_symbol=yes], + [grub_cv_check_uscore_start_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_uscore_start_symbol]) + +AH_TEMPLATE([START_SYMBOL], [Define it to either start or _start]) + +if test "x$grub_cv_check_start_symbol" = xyes; then + AC_DEFINE([START_SYMBOL], [start]) +elif test "x$grub_cv_check_uscore_start_symbol" = xyes; then + AC_DEFINE([START_SYMBOL], [_start]) +else + AC_MSG_ERROR([neither start nor _start is defined]) +fi +]) + +dnl Check what symbol is defined as a bss start symbol. +dnl Written by Michael Hohmoth and Yoshinori K. Okuji. +AC_DEFUN(grub_CHECK_BSS_START_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if __bss_start is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl __bss_start")]])], + [grub_cv_check_uscore_uscore_bss_start_symbol=yes], + [grub_cv_check_uscore_uscore_bss_start_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol]) + +AC_MSG_CHECKING([if edata is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_edata_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl edata")]])], + [grub_cv_check_edata_symbol=yes], + [grub_cv_check_edata_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_edata_symbol]) + +AC_MSG_CHECKING([if _edata is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl _edata")]])], + [grub_cv_check_uscore_edata_symbol=yes], + [grub_cv_check_uscore_edata_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol]) + +AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata]) + +if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [__bss_start]) +elif test "x$grub_cv_check_edata_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [edata]) +elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then + AC_DEFINE([BSS_START_SYMBOL], [_edata]) +else + AC_MSG_ERROR([none of __bss_start, edata or _edata is defined]) +fi +]) + +dnl Check what symbol is defined as an end symbol. +dnl Written by Yoshinori K. Okuji. +AC_DEFUN(grub_CHECK_END_SYMBOL, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if end is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_end_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl end")]])], + [grub_cv_check_end_symbol=yes], + [grub_cv_check_end_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_end_symbol]) + +AC_MSG_CHECKING([if _end is defined by the compiler]) +AC_CACHE_VAL(grub_cv_check_uscore_end_symbol, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], + [[asm ("incl _end")]])], + [grub_cv_check_uscore_end_symbol=yes], + [grub_cv_check_uscore_end_symbol=no])]) + +AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol]) + +AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end]) + +if test "x$grub_cv_check_end_symbol" = xyes; then + AC_DEFINE([END_SYMBOL], [end]) +elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then + AC_DEFINE([END_SYMBOL], [_end]) +else + AC_MSG_ERROR([neither end nor _end is defined]) +fi +]) + +dnl Check if the C compiler has a bug while using nested functions when +dnl mregparm is used on the i386. Some gcc versions do not pass the third +dnl parameter correctly to the nested function. +dnl Written by Marco Gerards. +AC_DEFUN(grub_I386_CHECK_REGPARM_BUG, +[AC_REQUIRE([AC_PROG_CC]) +AC_MSG_CHECKING([if GCC has the regparm=3 bug]) +AC_CACHE_VAL(grub_cv_i386_check_nested_functions, +[AC_RUN_IFELSE([AC_LANG_SOURCE( +[[ +static int +test (int *n) +{ + return *n == -1; +} + +static int +testfunc (int __attribute__ ((__regparm__ (3))) (*hook) (int a, int b, int *c)) +{ + int a = 0; + int b = 0; + int c = -1; + return hook (a, b, &c); +} + +int +main (void) +{ + int __attribute__ ((__regparm__ (3))) nestedfunc (int a, int b, int *c) + { + return a == b && test (c); + } + return testfunc (nestedfunc) ? 0 : 1; +} +]])], + [grub_cv_i386_check_nested_functions=no], + [grub_cv_i386_check_nested_functions=yes])]) + +AC_MSG_RESULT([$grub_cv_i386_check_nested_functions]) + +if test "x$grub_cv_i386_check_nested_functions" = xyes; then + AC_DEFINE([NESTED_FUNC_ATTR], + [__attribute__ ((__regparm__ (1)))], + [Catch gcc bug]) +else +dnl Unfortunately, the above test does not detect a bug in gcc-4.0. +dnl So use regparm 2 until a better test is found. + AC_DEFINE([NESTED_FUNC_ATTR], + [__attribute__ ((__regparm__ (1)))], + [Catch gcc bug]) +fi +]) + +dnl Check if the C compiler generates calls to `__enable_execute_stack()'. +AC_DEFUN(grub_CHECK_ENABLE_EXECUTE_STACK,[ +AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()']) +AC_LANG_CONFTEST([[ +void f (int (*p) (void)); +void g (int i) +{ + int nestedfunc (void) { return i; } + f (nestedfunc); +} +]]) +if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then + true +else + AC_MSG_ERROR([${CC-cc} failed to produce assembly code]) +fi +if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then + AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1, + [Define to 1 if GCC generates calls to __enable_execute_stack()]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +rm -f conftest* +]) + + +dnl Check if the C compiler supports `-fstack-protector'. +AC_DEFUN(grub_CHECK_STACK_PROTECTOR,[ +[# Smashing stack protector. +ssp_possible=yes] +AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) +# Is this a reliable test case? +AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) +[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling +# `ac_compile' like this correct, after all? +if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then] + AC_MSG_RESULT([yes]) + [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? + rm -f conftest.s +else + ssp_possible=no] + AC_MSG_RESULT([no]) +[fi] +]) + +dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin). +AC_DEFUN(grub_CHECK_STACK_ARG_PROBE,[ +[# Smashing stack arg probe. +sap_possible=yes] +AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe']) +AC_LANG_CONFTEST([[void foo (void) { volatile char a[8]; a[3]; }]]) +[if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then] + AC_MSG_RESULT([yes]) + [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'? + rm -f conftest.s +else + sap_possible=no] + AC_MSG_RESULT([no]) +[fi] +]) diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..6895de2 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +set -e + +autoconf +autoheader +echo timestamp > stamp-h.in +for rmk in conf/*.rmk; do + ruby genmk.rb < $rmk > `echo $rmk | sed 's/\.rmk$/.mk/'` +done +./gendistlist.sh > DISTLIST + +exit 0 diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S new file mode 100644 index 0000000..8056731 --- /dev/null +++ b/boot/i386/pc/boot.S @@ -0,0 +1,489 @@ +/* -*-Asm-*- */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +/* + * defines for the code go here + */ + + /* Absolute addresses + This makes the assembler generate the address without support + from the linker. (ELF can't relocate 16-bit addresses!) */ +#define ABS(x) (x-_start+0x7c00) + + /* Print message string */ +#define MSG(x) movw $ABS(x), %si; call message + + .file "boot.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + +.globl _start; _start: + /* + * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00 + */ + + /* + * Beginning of the sector is compatible with the FAT/HPFS BIOS + * parameter block. + */ + + jmp after_BPB + nop /* do I care about this ??? */ + + /* + * This space is for the BIOS parameter block!!!! Don't change + * the first jump, nor start the code anywhere but right after + * this area. + */ + + . = _start + 4 + + /* scratch space */ +mode: + .byte 0 +disk_address_packet: +sectors: + .long 0 +heads: + .long 0 +cylinders: + .word 0 +sector_start: + .byte 0 +head_start: + .byte 0 +cylinder_start: + .word 0 + /* more space... */ + + . = _start + GRUB_BOOT_MACHINE_BPB_END + + /* + * End of BIOS parameter block. + */ + +boot_version: + .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR +kernel_address: + .word GRUB_BOOT_MACHINE_KERNEL_ADDR +kernel_segment: + .word GRUB_BOOT_MACHINE_KERNEL_SEG +kernel_sector: + .long 1, 0 +boot_drive: + .byte 0xff /* the disk to load kernel from */ + /* 0xff means use the boot drive */ +root_drive: + .byte 0xff + +after_BPB: + +/* general setup */ + cli /* we're not safe here! */ + + /* + * This is a workaround for buggy BIOSes which don't pass boot + * drive correctly. If GRUB is installed into a HDD, check if + * DL is masked correctly. If not, assume that the BIOS passed + * a bogus value and set DL to 0x80, since this is the only + * possible boot drive. If GRUB is installed into a floppy, + * this does nothing (only jump). + */ +boot_drive_check: + jmp 1f /* grub-setup may overwrite this jump */ + testb $0x80, %dl + jnz 1f + movb $0x80, %dl +1: + + /* + * ljmp to the next instruction because some bogus BIOSes + * jump to 07C0:0000 instead of 0000:7C00. + */ + ljmp $0, $ABS(real_start) + +real_start: + + /* set up %ds and %ss as offset from 0 */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + + /* set up the REAL stack */ + movw $GRUB_BOOT_MACHINE_STACK_SEG, %sp + + sti /* we're safe again */ + + /* + * Check if we have a forced disk reference here + */ + /* assign root_drive at the same time */ + movw ABS(boot_drive), %ax + movb %ah, %dh + cmpb $0xff, %al + je 1f + movb %al, %dl +1: + /* save drive reference first thing! */ + pushw %dx + + /* print a notification message on the screen */ + MSG(notification_string) + + /* set %si to the disk address packet */ + movw $ABS(disk_address_packet), %si + + /* do not probe LBA if the drive is a floppy */ + testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl + jz chs_mode + + /* check if LBA is supported */ + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 + + /* + * %dl may have been clobbered by INT 13, AH=41H. + * This happens, for example, with AST BIOS 1.04. + */ + popw %dx + pushw %dx + + /* use CHS if fails */ + jc chs_mode + cmpw $0xaa55, %bx + jne chs_mode + + andw $1, %cx + jz chs_mode + +lba_mode: + xorw %ax, %ax + movw %ax, 4(%si) + + incw %ax + /* set the mode to non-zero */ + movb %al, -1(%si) + + /* the blocks */ + movw %ax, 2(%si) + + /* the size and the reserved byte */ + movw $0x0010, (%si) + + /* the absolute address */ + movl ABS(kernel_sector), %ebx + movl %ebx, 8(%si) + movl ABS(kernel_sector + 4), %ebx + movl %ebx, 12(%si) + + /* the segment of buffer address */ + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si) + +/* + * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory + * Call with %ah = 0x42 + * %dl = drive number + * %ds:%si = segment:offset of disk address packet + * Return: + * %al = 0x0 on success; err code on failure + */ + + movb $0x42, %ah + int $0x13 + + /* LBA read is not supported, so fallback to CHS. */ + jc chs_mode + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + jmp copy_buffer + +chs_mode: + /* + * Determine the hard disk geometry from the BIOS! + * We do this first, so that LS-120 IDE floppies work correctly. + */ + movb $8, %ah + int $0x13 + jnc final_init + + /* + * The call failed, so maybe use the floppy probe instead. + */ + testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl + jz floppy_probe + + /* Nope, we definitely have a hard disk, and we're screwed. */ + jmp hd_probe_error + +final_init: + /* set the mode to zero */ + movzbl %dh, %eax + movb %ah, -1(%si) + + /* save number of heads */ + incw %ax + movl %eax, 4(%si) + + movzbw %cl, %dx + shlw $2, %dx + movb %ch, %al + movb %dh, %ah + + /* save number of cylinders */ + incw %ax + movw %ax, 8(%si) + + movzbw %dl, %ax + shrb $2, %al + + /* save number of sectors */ + movl %eax, (%si) + +setup_sectors: + /* load logical sector start (top half) */ + movl ABS(kernel_sector + 4), %eax + orl %eax, %eax + jnz geometry_error + + /* load logical sector start (bottom half) */ + movl ABS(kernel_sector), %eax + + /* zero %edx */ + xorl %edx, %edx + + /* divide by number of sectors */ + divl (%si) + + /* save sector start */ + movb %dl, %cl + + xorw %dx, %dx /* zero %edx */ + divl 4(%si) /* divide by number of heads */ + + /* do we need too many cylinders? */ + cmpw 8(%si), %ax + jge geometry_error + + /* normalize sector start (1-based) */ + incb %cl + + /* low bits of cylinder start */ + movb %al, %ch + + /* high bits of cylinder start */ + xorb %al, %al + shrw $2, %ax + orb %al, %cl + + /* save head start */ + movb %dl, %al + + /* restore %dl */ + popw %dx + pushw %dx + + /* head start */ + movb %al, %dh + +/* + * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory + * Call with %ah = 0x2 + * %al = number of sectors + * %ch = cylinder + * %cl = sector (bits 6-7 are high bits of "cylinder") + * %dh = head + * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) + * %es:%bx = segment:offset of buffer + * Return: + * %al = 0x0 on success; err code on failure + */ + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es /* load %es segment with disk buffer */ + + xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */ + movw $0x0201, %ax /* function 2 */ + int $0x13 + + jc read_error + + movw %es, %bx + +copy_buffer: + movw ABS(kernel_segment), %es + + /* + * We need to save %cx and %si because the startup code in + * kernel uses them without initializing them. + */ + pusha + pushw %ds + + movw $0x100, %cx + movw %bx, %ds + xorw %si, %si + xorw %di, %di + + cld + + rep + movsw + + popw %ds + popa + popw %dx + + /* boot kernel */ + jmp *(kernel_address) + +/* END OF MAIN LOOP */ + +/* + * BIOS Geometry translation error (past the end of the disk geometry!). + */ +geometry_error: + MSG(geometry_error_string) + jmp general_error + +/* + * Disk probe failure. + */ +hd_probe_error: + MSG(hd_probe_error_string) + jmp general_error + +/* + * Read error on the disk. + */ +read_error: + MSG(read_error_string) + +general_error: + MSG(general_error_string) + +/* go here when you need to stop the machine hard after an error condition */ + /* tell the BIOS a boot failure, which may result in no effect */ + int $0x18 +stop: jmp stop + +notification_string: .string "GRUB " +geometry_error_string: .string "Geom" +hd_probe_error_string: .string "Hard Disk" +read_error_string: .string "Read" +general_error_string: .string " Error" + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + + /* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display a byte */ +message: + lodsb + cmpb $0, %al + jne 1b /* if not end of string, jmp to display */ + ret + + /* + * Windows NT breaks compatibility by embedding a magic + * number here. + */ + + . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC +nt_magic: + .long 0 + .word 0 + + /* + * This is where an MBR would go if on a hard disk. The code + * here isn't even referenced unless we're on a floppy. Kinda + * sneaky, huh? + */ + +part_start: + . = _start + GRUB_BOOT_MACHINE_PART_START + +probe_values: + .byte 36, 18, 15, 9, 0 + +floppy_probe: +/* + * Perform floppy probe. + */ + + movw $ABS(probe_values-1), %si + +probe_loop: + /* reset floppy controller INT 13h AH=0 */ + xorw %ax, %ax + int $0x13 + + incw %si + movb (%si), %cl + + /* if number of sectors is 0, display error and die */ + cmpb $0, %cl + jne 1f + +/* + * Floppy disk probe failure. + */ + MSG(fd_probe_error_string) + jmp general_error + +fd_probe_error_string: .string "Floppy" + +1: + /* perform read */ + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw $0x201, %ax + movb $0, %ch + movb $0, %dh + int $0x13 + + /* if error, jump to "probe_loop" */ + jc probe_loop + + /* %cl is already the correct value! */ + movb $1, %dh + movb $79, %ch + + jmp final_init + + . = _start + GRUB_BOOT_MACHINE_PART_END + +/* the last 2 bytes in the sector 0 contain the signature */ + .word GRUB_BOOT_MACHINE_SIGNATURE diff --git a/boot/i386/pc/cdboot.S b/boot/i386/pc/cdboot.S new file mode 100644 index 0000000..02d4fce --- /dev/null +++ b/boot/i386/pc/cdboot.S @@ -0,0 +1,175 @@ +/* -*-Asm-*- */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + + .file "cdboot.S" + +#define CODE_ADDR 0x6000 +#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200) + +#define CDSEC_SHIFT 11 +#define CDBLK_LENG 16 + + .text + + .code16 + + .globl start, _start + +start: +_start: + call next + +next: + jmp 1f + + . = start + 8 + +bi_pvd: + .long 0 /* LBA of primary volume descript. */ +bi_file: + .long 0 /* LBA of boot file. */ +bi_length: + .long 0 /* Length of boot file. */ +bi_csum: + .long 0 /* Checksum of boot file */ +bi_reserved: + .space (10*4) /* Reserved */ + +1: + popw %bx + + /* Boot from CDROM. */ + + xorw %ax, %ax + movw %ax, %ss + movw $(CODE_ADDR), %sp + movw %ax, %ds + movw %ax, %es + + movw $(0x7C00 + err_noboot_msg - start), %si + movl %cs: bi_length - next(%bx), %ecx + orl %ecx, %ecx + jz fail + + addl $((1 << CDSEC_SHIFT) - 1), %ecx + shrl $CDSEC_SHIFT, %ecx + + movl %cs: bi_file - next(%bx), %esi + + call read_cdrom + + /* Root drive will default to boot drive */ + movb $0xFF, %dh + + ljmp $(DATA_ADDR >> 4), $0 + +/* + * Parameters: + * esi: start sector + * ecx: number of sectors + */ +read_cdrom: + xorl %eax, %eax + + /* Number of blocks to read. */ + pushw $CDBLK_LENG + + /* Block number. */ + pushl %eax + pushl %esi + + /* Buffer address. */ + pushw $((DATA_ADDR - 0x400)>> 4) + pushl %eax + pushw $0x10 + + xorl %edi, %edi + movw %sp, %si + +1: + movw 0x10(%si), %di + cmpl %ecx, %edi + jbe 2f + movl %ecx, %edi + +2: + mov %di, 2(%si) + + pushl %ecx + + movb $0x42, %ah + int $0x13 + + jnc 3f + + movb $0x42, %ah /* Try again. */ + int $0x13 + + jnc 3f + +2: + shrw $1, %di /* Reduce transfer size. */ + jz cdrom_fail + movw %di, 0x10(%si) + movw %di, 2(%si) + movb $0x42, %ah + int $0x13 + jc 2b + +3: + + movw %di, %ax + shlw $(CDSEC_SHIFT - 4), %ax + addw %ax, 6(%si) + addl %edi, 8(%si) + + popl %ecx + subl %edi, %ecx + jnz 1b + + addw $0x12, %sp + ret + +cdrom_fail: + movw $(0x7C00 + err_cdfail_msg - start), %si + +fail: + movb $0x0e, %ah + xorw %bx, %bx +1: + lodsb (%si), %al + int $0x10 + cmpb $0, %al + jne 1b +1: jmp 1b + +err_noboot_msg: + .ascii "no boot info\0" + +err_cdfail_msg: + .ascii "cdrom read fails\0" + + . = start + 0x1FF + + .byte 0 diff --git a/boot/i386/pc/diskboot.S b/boot/i386/pc/diskboot.S new file mode 100644 index 0000000..95f87a0 --- /dev/null +++ b/boot/i386/pc/diskboot.S @@ -0,0 +1,387 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +/* + * defines for the code go here + */ + + /* Absolute addresses + This makes the assembler generate the address without support + from the linker. (ELF can't relocate 16-bit addresses!) */ +#define ABS(x) (x-_start+GRUB_BOOT_MACHINE_KERNEL_ADDR) + + /* Print message string */ +#define MSG(x) movw $ABS(x), %si; call message + + .file "diskboot.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: + /* + * _start is loaded at 0x2000 and is jumped to with + * CS:IP 0:0x2000 in kernel. + */ + + /* + * we continue to use the stack for boot.img and assume that + * some registers are set to correct values. See boot.S + * for more information. + */ + + /* save drive reference first thing! */ + pushw %dx + + /* print a notification message on the screen */ + pushw %si + MSG(notification_string) + popw %si + + /* this sets up for the first run through "bootloop" */ + movw $ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE), %di + + /* save the sector number of the second sector in %ebp */ + movl (%di), %ebp + + /* this is the loop for reading the rest of the kernel in */ +bootloop: + + /* check the number of sectors to read */ + cmpw $0, 8(%di) + + /* if zero, go to the start function */ + je bootit + +setup_sectors: + /* check if we use LBA or CHS */ + cmpb $0, -1(%si) + + /* jump to chs_mode if zero */ + je chs_mode + +lba_mode: + /* load logical sector start */ + movl (%di), %ebx + movl 4(%di), %ecx + + /* the maximum is limited to 0x7f because of Phoenix EDD */ + xorl %eax, %eax + movb $0x7f, %al + + /* how many do we really want to read? */ + cmpw %ax, 8(%di) /* compare against total number of sectors */ + + /* which is greater? */ + jg 1f + + /* if less than, set to total */ + movw 8(%di), %ax + +1: + /* subtract from total */ + subw %ax, 8(%di) + + /* add into logical sector start */ + addl %eax, (%di) + adcl $0, 4(%di) + + /* set up disk address packet */ + + /* the size and the reserved byte */ + movw $0x0010, (%si) + + /* the number of sectors */ + movw %ax, 2(%si) + + /* the absolute address */ + movl %ebx, 8(%si) + movl %ecx, 12(%si) + + /* the segment of buffer address */ + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si) + + /* save %ax from destruction! */ + pushw %ax + + /* the offset of buffer address */ + movw $0, 4(%si) + +/* + * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory + * Call with %ah = 0x42 + * %dl = drive number + * %ds:%si = segment:offset of disk address packet + * Return: + * %al = 0x0 on success; err code on failure + */ + + movb $0x42, %ah + int $0x13 + + jc read_error + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + jmp copy_buffer + +chs_mode: + /* load logical sector start (top half) */ + movl 4(%di), %eax + orl %eax, %eax + jnz geometry_error + + /* load logical sector start (bottom half) */ + movl (%di), %eax + + /* zero %edx */ + xorl %edx, %edx + + /* divide by number of sectors */ + divl (%si) + + /* save sector start */ + movb %dl, 10(%si) + + xorl %edx, %edx /* zero %edx */ + divl 4(%si) /* divide by number of heads */ + + /* save head start */ + movb %dl, 11(%si) + + /* save cylinder start */ + movw %ax, 12(%si) + + /* do we need too many cylinders? */ + cmpw 8(%si), %ax + jge geometry_error + + /* determine the maximum sector length of this read */ + movw (%si), %ax /* get number of sectors per track/head */ + + /* subtract sector start */ + subb 10(%si), %al + + /* how many do we really want to read? */ + cmpw %ax, 8(%di) /* compare against total number of sectors */ + + + /* which is greater? */ + jg 2f + + /* if less than, set to total */ + movw 8(%di), %ax + +2: + /* subtract from total */ + subw %ax, 8(%di) + + /* add into logical sector start */ + addl %eax, (%di) + adcl $0, 4(%di) + +/* + * This is the loop for taking care of BIOS geometry translation (ugh!) + */ + + /* get high bits of cylinder */ + movb 13(%si), %dl + + shlb $6, %dl /* shift left by 6 bits */ + movb 10(%si), %cl /* get sector */ + + incb %cl /* normalize sector (sectors go + from 1-N, not 0-(N-1) ) */ + orb %dl, %cl /* composite together */ + movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */ + + /* restore %dx */ + popw %dx + pushw %dx + + /* head number */ + movb 11(%si), %dh + + pushw %ax /* save %ax from destruction! */ + +/* + * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory + * Call with %ah = 0x2 + * %al = number of sectors + * %ch = cylinder + * %cl = sector (bits 6-7 are high bits of "cylinder") + * %dh = head + * %dl = drive (0x80 for hard disk, 0x0 for floppy disk) + * %es:%bx = segment:offset of buffer + * Return: + * %al = 0x0 on success; err code on failure + */ + + movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw %bx, %es /* load %es segment with disk buffer */ + + xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */ + movb $0x2, %ah /* function 2 */ + int $0x13 + + jc read_error + + /* save source segment */ + movw %es, %bx + +copy_buffer: + + /* load addresses for copy from disk buffer to destination */ + movw 10(%di), %es /* load destination segment */ + + /* restore %ax */ + popw %ax + + /* determine the next possible destination address (presuming + 512 byte sectors!) */ + shlw $5, %ax /* shift %ax five bits to the left */ + addw %ax, 10(%di) /* add the corrected value to the destination + address for next time */ + + /* save addressing regs */ + pusha + pushw %ds + + /* get the copy length */ + shlw $3, %ax + movw %ax, %cx + + xorw %di, %di /* zero offset of destination addresses */ + xorw %si, %si /* zero offset of source addresses */ + movw %bx, %ds /* restore the source segment */ + + cld /* sets the copy direction to forward */ + + /* perform copy */ + rep /* sets a repeat */ + movsw /* this runs the actual copy */ + + /* restore addressing regs and print a dot with correct DS + (MSG modifies SI, which is saved, and unused AX and BX) */ + popw %ds + MSG(notification_step) + popa + + /* check if finished with this dataset */ + cmpw $0, 8(%di) + jne setup_sectors + + /* update position to load from */ + subw $GRUB_BOOT_MACHINE_LIST_SIZE, %di + + /* jump to bootloop */ + jmp bootloop + +/* END OF MAIN LOOP */ + +bootit: + /* print a newline */ + MSG(notification_done) + popw %dx /* this makes sure %dl is our "boot" drive */ + ljmp $0, $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + +/* + * BIOS Geometry translation error (past the end of the disk geometry!). + */ +geometry_error: + MSG(geometry_error_string) + jmp general_error + +/* + * Read error on the disk. + */ +read_error: + MSG(read_error_string) + +general_error: + MSG(general_error_string) + +/* go here when you need to stop the machine hard after an error condition */ +stop: jmp stop + +notification_string: .string "loading" + +notification_step: .string "." +notification_done: .string "\r\n" + +geometry_error_string: .string "Geom" +read_error_string: .string "Read" +general_error_string: .string " Error" + +/* + * message: write the string pointed to by %si + * + * WARNING: trashes %si, %ax, and %bx + */ + + /* + * Use BIOS "int 10H Function 0Eh" to write character in teletype mode + * %ah = 0xe %al = character + * %bh = page %bl = foreground color (graphics modes) + */ +1: + movw $0x0001, %bx + movb $0xe, %ah + int $0x10 /* display a byte */ + + incw %si +message: + movb (%si), %al + cmpb $0, %al + jne 1b /* if not end of string, jmp to display */ + ret +lastlist: + +/* + * This area is an empty space between the main body of code below which + * grows up (fixed after compilation, but between releases it may change + * in size easily), and the lists of sectors to read, which grows down + * from a fixed top location. + */ + + .word 0 + .word 0 + + . = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE + + /* fill the first data listing with the default */ +blocklist_default_start: + /* this is the sector start parameter, in logical sectors from + the start of the disk, sector 0 */ + .long 2, 0 +blocklist_default_len: + /* this is the number of sectors to read the command "install" + will fill this up */ + .word 0 +blocklist_default_seg: + /* this is the segment of the starting address to load the data into */ + .word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20) + +firstlist: /* this label has to be after the list data!!! */ diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S new file mode 100644 index 0000000..e7f55df --- /dev/null +++ b/boot/i386/pc/lnxboot.S @@ -0,0 +1,296 @@ +/* -*-Asm-*- */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + + .file "lnxboot.S" + +#define CODE_ADDR 0x6000 +#define CODE_LENG (code_end - start) +#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200) + +#define BLCK_LENG 0x4000 + + .text + + .code16 + + .globl start, _start + +data_start: + xorl %ebp, %ebp + jmp linux_next + + . = data_start + 0x1F1 + +setup_sects: + .byte (CODE_LENG >> 9) +root_flags: + .word 0 +syssize: + .word 0 +swap_dev: + .word 0 +ram_size: + .word 0 +vid_mode: + .word 0 +root_dev: + .word 0 +boot_flag: + .word 0xAA55 + +start: +_start: + + jmp linux_init + + .ascii "HdrS" /* Header signature. */ + .word 0x0203 /* Header version number. */ + +realmode_swtch: + .word 0, 0 /* default_switch, SETUPSEG. */ +start_sys_seg: + .word 0x1000 /* Obsolete. */ +version_ptr: + .word 0 /* Version string ptr. */ +type_of_loader: + .byte 0 /* Filled in by boot loader. */ +loadflags: + .byte 1 /* Please load high. */ +setup_move_size: + .word 0 /* Unused. */ +code32_start: + .long 0x100000 /* 32-bit start address. */ +ramdisk_image: + .long 0 /* Loaded ramdisk image address. */ +ramdisk_size: + .long 0 /* Size of loaded ramdisk. */ +bootsect_kludge: + .word 0, 0 +heap_end_ptr: + .word 0 +pad1: + .word 0 +cmd_line_ptr: + .long 0 /* Command line. */ +ramdisk_max: + .long 0xffffffff /* Highest allowed ramdisk address. */ + +gdt: + .long 0, 0, 0, 0 /* Must be zero. */ + .word 0xffff /* 64 K segment size. */ +gdt_src1: + .byte 0, 0 ,0 /* Low 24 bits of source address. */ + .byte 0x93 /* Access rights. */ + .byte 0 /* Extended access rights. */ +gdt_src2: + .byte 0 /* High 8 bits of source address. */ + .word 0xffff /* 64 K segment size. */ +gdt_dst1: + .byte 0, 0, 0 /* Low 24 bits of target address. */ + .byte 0x93 /* Access rights. */ + .byte 0 /* Extended access rights. */ +gdt_dst2: + .byte 0 /* High 8 bits of source address. */ + .long 0, 0, 0, 0 /* More space for the BIOS. */ + +reg_edx: + .byte 0x80, 0, 0xFF, 0xFF + +data_leng: + .long 0 + +linux_init: + + movw %cs:(reg_edx - start), %dx + movl %cs:(code32_start - start), %ebp + +linux_next: + + call normalize + +normalize: + popw %bx + subw $(normalize - start), %bx + shrw $4, %bx + movw %cs, %ax + addw %bx, %ax + pushw %ax + pushw $(real_code - start) + lret /* Jump to real_code. */ + +real_code: + subw $0x20, %ax + movw %ax, %ds + movw (setup_sects - data_start), %cx + shlw $7, %cx + + /* Setup stack. */ + + xorw %si, %si + movw %si, %ss + movw $(CODE_ADDR), %sp + + /* Move itself to 0:CODE_ADDR. */ + + cld + movw %cs, %ax + movw %ax, %ds + movw $(CODE_ADDR >> 4), %ax + movw %ax, %es + movw %si, %di + + rep + movsl + + ljmp $(CODE_ADDR >> 4), $(real_code_2 - start) + +real_code_2: + + xchgl %ebp, %esi + orl %esi, %esi + jnz 1f + movw %ds, %si + shll $4, %esi + addl %ebp, %esi +1: + + pushw %es + popw %ds + + movl $0x200, %ecx + addl %ecx, %esi + movl $DATA_ADDR, %edi + + call move_memory + + /* Check for multiboot signature. */ + cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) + jz 1f + + movl (ramdisk_image - start), %esi + movl (ramdisk_size - start), %ecx + movl $(DATA_ADDR - 0x200), %edi + jmp 2f + +1: + + movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx + addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx + +2: + call move_memory + + movsbl %dh, %eax + movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) + + movsbl (reg_edx + 2 - start), %eax + movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) + + movb $0xFF, %dh + + ljmp $(DATA_ADDR >> 4), $0 + +/* + * Parameters: + * esi: source address + * edi: target address + * ecx: number of bytes + */ + +move_memory: + incl %ecx + andb $0xFE, %cl + pushw %dx +1: + pushl %esi + pushl %edi + pushl %ecx + cmpl $BLCK_LENG, %ecx + jbe 2f + movl $BLCK_LENG, %ecx +2: + pushl %ecx + + movl %esi, %eax + movw %si, (gdt_src1 - start) + shrl $16, %eax + movb %al, (gdt_src1 + 2 - start) + movb %ah, (gdt_src2 - start) + + movl %edi, %eax + movw %di, (gdt_dst1 - start) + shrl $16, %eax + movb %al, (gdt_dst1 + 2 - start) + movb %ah, (gdt_dst2 - start) + + movw $(gdt - start), %si + movb $0x87, %ah + shrw $1, %cx + + int $0x15 + + popl %eax + popl %ecx + popl %edi + popl %esi + + jnc 2f + movw $(err_int15_msg - start), %si + jmp fail + +2: + + addl %eax, %esi + addl %eax, %edi + subl %eax, %ecx + jnz 1b + + + popw %dx + ret + +/* + * Parameters: + * si: message + */ + +fail: + movb $0x0e, %ah + xorw %bx, %bx +1: + lodsb (%si), %al + int $0x10 + cmpb $0, %al + jne 1b +1: jmp 1b + +err_int15_msg: + .ascii "move memory fails\0" + + . = (. & (~0x1FF)) + 0x1FF + + .byte 0 + +code_end: diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S new file mode 100644 index 0000000..4fdff76 --- /dev/null +++ b/boot/i386/pc/pxeboot.S @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + .file "pxeboot.S" + .text + + /* Start with the prehistoric environment... */ + .code16 + + /* Let's go */ +.globl _start; _start: + + /* Root drive will default to boot drive */ + movb $0xFF, %dh + movb $0x7F, %dl + + /* Jump to the real world */ + ljmp $0, $0x8200 + + /* This region is a junk. Do you say that this is wasteful? + But I like that the memory layout of the body is consistent + among different kernels rather than scamping just for 1.5KB. */ + . = _start + 0x8200 - 0x7C00 - 0x200 - 1 + .byte 0 diff --git a/bus/pci.c b/bus/pci.c new file mode 100644 index 0000000..2c29c03 --- /dev/null +++ b/bus/pci.c @@ -0,0 +1,66 @@ +/* pci.c - Generic PCI interfaces. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +grub_pci_address_t +grub_pci_make_address (int bus, int device, int function, int reg) +{ + return (1 << 31) | (bus << 16) | (device << 11) | (function << 8) | (reg << 2); +} + +void +grub_pci_iterate (grub_pci_iteratefunc_t hook) +{ + int bus; + int dev; + int func; + grub_pci_address_t addr; + grub_pci_id_t id; + grub_uint32_t hdr; + + for (bus = 0; bus < 256; bus++) + { + for (dev = 0; dev < 32; dev++) + { + for (func = 0; func < 8; func++) + { + addr = grub_pci_make_address (bus, dev, func, 0); + id = grub_pci_read (addr); + + /* Check if there is a device present. */ + if (id >> 16 == 0xFFFF) + continue; + + if (hook (bus, dev, func, id)) + return; + + /* Probe only func = 0 if the device if not multifunction */ + if (func == 0) + { + addr = grub_pci_make_address (bus, dev, func, 3); + hdr = grub_pci_read (addr); + if (!(hdr & 0x800000)) + break; + } + } + } + } +} diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c new file mode 100644 index 0000000..d2e78d4 --- /dev/null +++ b/bus/usb/ohci.c @@ -0,0 +1,608 @@ +/* ohci.c - OHCI Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_ohci_hcca +{ + /* Pointers to Interrupt Endpoint Descriptors. Not used by + GRUB. */ + grub_uint32_t inttable[32]; + + /* Current frame number. */ + grub_uint16_t framenumber; + + grub_uint16_t pad; + + /* List of completed TDs. */ + grub_uint32_t donehead; + + grub_uint8_t reserved[116]; +} __attribute__((packed)); + +/* OHCI Endpoint Descriptor. */ +struct grub_ohci_ed +{ + grub_uint32_t target; + grub_uint32_t td_tail; + grub_uint32_t td_head; + grub_uint32_t next_ed; +} __attribute__((packed)); + +struct grub_ohci_td +{ + /* Information used to construct the TOKEN packet. */ + grub_uint32_t token; + + grub_uint32_t buffer; + grub_uint32_t next_td; + grub_uint32_t buffer_end; +} __attribute__((packed)); + +typedef struct grub_ohci_td *grub_ohci_td_t; +typedef struct grub_ohci_ed *grub_ohci_ed_t; + +struct grub_ohci +{ + volatile grub_uint32_t *iobase; + volatile struct grub_ohci_hcca *hcca; + struct grub_ohci *next; +}; + +static struct grub_ohci *ohci; + +typedef enum +{ + GRUB_OHCI_REG_REVISION = 0x00, + GRUB_OHCI_REG_CONTROL, + GRUB_OHCI_REG_CMDSTATUS, + GRUB_OHCI_REG_INTSTATUS, + GRUB_OHCI_REG_INTENA, + GRUB_OHCI_REG_INTDIS, + GRUB_OHCI_REG_HCCA, + GRUB_OHCI_REG_PERIODIC, + GRUB_OHCI_REG_CONTROLHEAD, + GRUB_OHCI_REG_CONTROLCURR, + GRUB_OHCI_REG_BULKHEAD, + GRUB_OHCI_REG_BULKCURR, + GRUB_OHCI_REG_DONEHEAD, + GRUB_OHCI_REG_FRAME_INTERVAL, + GRUB_OHCI_REG_RHUBA = 18, + GRUB_OHCI_REG_RHUBPORT = 21 +} grub_ohci_reg_t; + +static grub_uint32_t +grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) +{ + return grub_le_to_cpu32 (*(o->iobase + reg)); +} + +static void +grub_ohci_writereg32 (struct grub_ohci *o, + grub_ohci_reg_t reg, grub_uint32_t val) +{ + *(o->iobase + reg) = grub_cpu_to_le32 (val); +} + + + +/* Iterate over all PCI devices. Determine if a device is an OHCI + controller. If this is the case, initialize it. */ +static int grub_ohci_pci_iter (int bus, int device, int func, + grub_pci_id_t pciid __attribute__((unused))) +{ + grub_uint32_t class; + grub_uint32_t subclass; + int interf; + grub_uint32_t base; + grub_pci_address_t addr; + struct grub_ohci *o; + grub_uint32_t revision; + grub_uint32_t frame_interval; + + addr = grub_pci_make_address (bus, device, func, 2); + class = grub_pci_read (addr); + addr = grub_pci_make_address (bus, device, func, 2); + class = grub_pci_read (addr); + + interf = class & 0xFF; + subclass = (class >> 16) & 0xFF; + class >>= 24; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03) + return 0; + + /* Determine IO base address. */ + addr = grub_pci_make_address (bus, device, func, 4); + base = grub_pci_read (addr); + +#if 0 + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; +#endif + + /* Allocate memory for the controller and register it. */ + o = grub_malloc (sizeof (*o)); + if (! o) + return 1; + + /* Link in the OHCI. */ + o->next = ohci; + ohci = o; + o->iobase = (grub_uint32_t *) base; + + /* Reserve memory for the HCCA. */ + o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); + + /* Check if the OHCI revision is actually 1.0 as supported. */ + revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); + grub_dprintf ("ohci", "OHCI revision=0x%02x\n", revision & 0xFF); + if ((revision & 0xFF) != 0x10) + goto fail; + + /* Backup the frame interval register. */ + frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); + + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. + */ + grub_millisleep (1); + grub_dprintf ("ohci", "OHCI reset\n"); + + /* Restore the frame interval register. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); + + /* Setup the HCCA. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_dprintf ("ohci", "OHCI HCCA\n"); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + (2 << 6)); + grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); + + return 0; + + fail: + if (o) + grub_free ((void *) o->hcca); + grub_free (o); + + return 1; +} + + +static void +grub_ohci_inithw (void) +{ + grub_pci_iterate (grub_ohci_pci_iter); +} + + + +static int +grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) +{ + struct grub_ohci *o; + struct grub_usb_controller dev; + + for (o = ohci; o; o = o->next) + { + dev.data = o; + if (hook (&dev)) + return 1; + } + + return 0; +} + +static void +grub_ohci_transaction (grub_ohci_td_t td, + grub_transfer_type_t type, unsigned int toggle, + grub_size_t size, char *data) +{ + grub_uint32_t token; + grub_uint32_t buffer; + grub_uint32_t buffer_end; + + grub_dprintf ("ohci", "OHCI transaction td=0x%02x type=%d, toggle=%d, size=%d\n", + td, type, toggle, size); + + switch (type) + { + case GRUB_USB_TRANSFER_TYPE_SETUP: + token = 0 << 19; + break; + case GRUB_USB_TRANSFER_TYPE_IN: + token = 2 << 19; + break; + case GRUB_USB_TRANSFER_TYPE_OUT: + token = 1 << 19; + break; + default: + token = 0; + break; + } + + /* Generate no interrupts. */ + token |= 7 << 21; + + /* Set the token. */ + token |= toggle << 24; + token |= 1 << 25; + + buffer = (grub_uint32_t) data; + buffer_end = buffer + size - 1; + + td->token = grub_cpu_to_le32 (token); + td->buffer = grub_cpu_to_le32 (buffer); + td->next_td = 0; + td->buffer_end = grub_cpu_to_le32 (buffer_end); +} + +static grub_usb_err_t +grub_ohci_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_ohci *o = (struct grub_ohci *) dev->data; + grub_ohci_ed_t ed; + grub_ohci_td_t td_list; + grub_uint32_t target; + grub_uint32_t td_tail; + grub_uint32_t td_head; + grub_uint32_t status; + grub_uint32_t control; + grub_usb_err_t err; + int i; + + /* Allocate an Endpoint Descriptor. */ + ed = grub_memalign (16, sizeof (*ed)); + if (! ed) + return GRUB_USB_ERR_INTERNAL; + + td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); + if (! td_list) + { + grub_free ((void *) ed); + return GRUB_USB_ERR_INTERNAL; + } + + grub_dprintf ("ohci", "alloc=0x%08x\n", td_list); + + /* Setup all Transfer Descriptors. */ + for (i = 0; i < transfer->transcnt; i++) + { + grub_usb_transaction_t tr = &transfer->transactions[i]; + + grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, + tr->size, tr->data); + + td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); + } + + /* Setup the Endpoint Descriptor. */ + + /* Set the device address. */ + target = transfer->devaddr; + + /* Set the endpoint. */ + target |= transfer->endpoint << 7; + + /* Set the device speed. */ + target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; + + /* Set the maximum packet size. */ + target |= transfer->max << 16; + + td_head = (grub_uint32_t) td_list; + + td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + + ed->target = grub_cpu_to_le32 (target); + ed->td_head = grub_cpu_to_le32 (td_head); + ed->td_tail = grub_cpu_to_le32 (td_tail); + ed->next_ed = grub_cpu_to_le32 (0); + + grub_dprintf ("ohci", "program OHCI\n"); + + /* Program the OHCI to actually transfer. */ + switch (transfer->type) + { + case GRUB_USB_TRANSACTION_TYPE_BULK: + { + grub_dprintf ("ohci", "add to bulk list\n"); + + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + + /* Disable the Control and Bulk lists. */ + control &= ~(3 << 4); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Clear BulkListFilled. */ + status &= ~(1 << 2); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + + /* Enable the Bulk list. */ + control |= 1 << 5; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Set BulkListFilled. */ + status |= 1 << 2; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + break; + } + + case GRUB_USB_TRANSACTION_TYPE_CONTROL: + { + grub_dprintf ("ohci", "add to control list\n"); + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + + /* Disable the Control and Bulk lists. */ + control &= ~(3 << 4); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Clear ControlListFilled. */ + status &= ~(1 << 1); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, + (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, + (grub_uint32_t) ed); + + /* Enable the Control list. */ + control |= 1 << 4; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Set ControlListFilled. */ + status |= 1 << 1; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + break; + } + } + + grub_dprintf ("ohci", "wait for completion\n"); + grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + + /* Wait until the transfer is completed or STALLs. */ + while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf)) + { + grub_cpu_idle (); + + grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail); + + /* Detected a STALL. */ + if (ed->td_head & 1) + break; + } + + grub_dprintf ("ohci", "complete\n"); + +/* if (ed->td_head & 1) */ +/* err = GRUB_USB_ERR_STALL; */ +/* else if (ed->td */ + + + if (ed->td_head & 1) + { + grub_uint8_t errcode; + grub_ohci_td_t tderr; + + tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, + GRUB_OHCI_REG_DONEHEAD); + errcode = tderr->token >> 28; + + switch (errcode) + { + case 0: + /* XXX: Should not happen! */ + grub_error (GRUB_ERR_IO, "OHCI without reporting the reason"); + err = GRUB_USB_ERR_INTERNAL; + break; + + case 1: + /* XXX: CRC error. */ + err = GRUB_USB_ERR_TIMEOUT; + break; + + case 2: + err = GRUB_USB_ERR_BITSTUFF; + break; + + case 3: + /* XXX: Data Toggle error. */ + err = GRUB_USB_ERR_DATA; + break; + + case 4: + err = GRUB_USB_ERR_STALL; + break; + + case 5: + /* XXX: Not responding. */ + err = GRUB_USB_ERR_TIMEOUT; + break; + + case 6: + /* XXX: PID Check bits failed. */ + err = GRUB_USB_ERR_BABBLE; + break; + + case 7: + /* XXX: PID unexpected failed. */ + err = GRUB_USB_ERR_BABBLE; + break; + + case 8: + /* XXX: Data overrun error. */ + err = GRUB_USB_ERR_DATA; + break; + + case 9: + /* XXX: Data underrun error. */ + err = GRUB_USB_ERR_DATA; + break; + + case 10: + /* XXX: Reserved. */ + err = GRUB_USB_ERR_NAK; + break; + + case 11: + /* XXX: Reserved. */ + err = GRUB_USB_ERR_NAK; + break; + + case 12: + /* XXX: Buffer overrun. */ + err = GRUB_USB_ERR_DATA; + break; + + case 13: + /* XXX: Buffer underrun. */ + err = GRUB_USB_ERR_DATA; + break; + + default: + err = GRUB_USB_ERR_NAK; + break; + } + } + else + err = GRUB_USB_ERR_NONE; + + /* Disable the Control and Bulk lists. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + control &= ~(3 << 4); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Clear BulkListFilled and ControlListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + status &= ~((1 << 2) | (1 << 3)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + /* XXX */ + grub_free (td_list); + grub_free (ed); + + return err; +} + +static grub_err_t +grub_ohci_portstatus (grub_usb_controller_t dev, + unsigned int port, unsigned int enable) +{ + struct grub_ohci *o = (struct grub_ohci *) dev->data; + grub_uint32_t status; + + /* Reset the port. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + status |= (1 << 4); /* XXX: Magic. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); + grub_millisleep (100); + + /* End the reset signaling. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + status |= (1 << 20); /* XXX: Magic. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); + grub_millisleep (10); + + /* Enable the port. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + status |= (enable << 1); /* XXX: Magic. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); + + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + grub_dprintf ("ohci", "portstatus=0x%02x\n", status); + + return GRUB_ERR_NONE; +} + +static grub_usb_speed_t +grub_ohci_detect_dev (grub_usb_controller_t dev, int port) +{ + struct grub_ohci *o = (struct grub_ohci *) dev->data; + grub_uint32_t status; + + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); + + grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status); + + if (! (status & 1)) + return GRUB_USB_SPEED_NONE; + else if (status & (1 << 9)) + return GRUB_USB_SPEED_LOW; + else + return GRUB_USB_SPEED_FULL; +} + +static int +grub_ohci_hubports (grub_usb_controller_t dev) +{ + struct grub_ohci *o = (struct grub_ohci *) dev->data; + grub_uint32_t portinfo; + + portinfo = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA); + + grub_dprintf ("ohci", "root hub ports=%d\n", portinfo & 0xFF); + + /* The root hub has exactly two ports. */ + return portinfo & 0xFF; +} + + + +static struct grub_usb_controller_dev usb_controller = +{ + .name = "ohci", + .iterate = grub_ohci_iterate, + .transfer = grub_ohci_transfer, + .hubports = grub_ohci_hubports, + .portstatus = grub_ohci_portstatus, + .detect_dev = grub_ohci_detect_dev +}; + +GRUB_MOD_INIT(ohci) +{ + grub_ohci_inithw (); + grub_usb_controller_dev_register (&usb_controller); +} + +GRUB_MOD_FINI(ohci) +{ + grub_usb_controller_dev_unregister (&usb_controller); +} diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c new file mode 100644 index 0000000..c59c0ca --- /dev/null +++ b/bus/usb/uhci.c @@ -0,0 +1,675 @@ +/* uhci.c - UHCI Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_UHCI_IOMASK (0x7FF << 5) + +typedef enum + { + GRUB_UHCI_REG_USBCMD = 0x00, + GRUB_UHCI_REG_FLBASEADD = 0x08, + GRUB_UHCI_REG_PORTSC1 = 0x10, + GRUB_UHCI_REG_PORTSC2 = 0x12 + } grub_uhci_reg_t; + +#define GRUB_UHCI_LINK_TERMINATE 1 +#define GRUB_UHCI_LINK_QUEUE_HEAD 2 + + +/* UHCI Queue Head. */ +struct grub_uhci_qh +{ + /* Queue head link pointer which points to the next queue head. */ + grub_uint32_t linkptr; + + /* Queue element link pointer which points to the first data object + within the queue. */ + grub_uint32_t elinkptr; + + /* Queue heads are aligned on 16 bytes, pad so a queue head is 16 + bytes so we can store many in a 4K page. */ + grub_uint8_t pad[8]; +} __attribute__ ((packed)); + +/* UHCI Tranfer Descriptor. */ +struct grub_uhci_td +{ + /* Pointer to the next TD in the list. */ + grub_uint32_t linkptr; + + /* Control and status bits. */ + grub_uint32_t ctrl_status; + + /* All information required to transfer the Token packet. */ + grub_uint32_t token; + + /* A pointer to the data buffer, UHCI requires this pointer to be 32 + bits. */ + grub_uint32_t buffer; + + /* Another linkptr that is not overwritten by the Host Controller. + This is GRUB specific. */ + grub_uint32_t linkptr2; + + /* 3 additional 32 bits words reserved for the Host Controller Driver. */ + grub_uint32_t data[3]; +} __attribute__ ((packed)); + +typedef volatile struct grub_uhci_td *grub_uhci_td_t; +typedef volatile struct grub_uhci_qh *grub_uhci_qh_t; + +struct grub_uhci +{ + int iobase; + grub_uint32_t *framelist; + + /* 256 Queue Heads. */ + grub_uhci_qh_t qh; + + /* 256 Transfer Descriptors. */ + grub_uhci_td_t td; + + /* Free Transfer Descriptors. */ + grub_uhci_td_t tdfree; + + struct grub_uhci *next; +}; + +static struct grub_uhci *uhci; + +static grub_uint16_t +grub_uhci_readreg16 (struct grub_uhci *u, grub_uhci_reg_t reg) +{ + return grub_inw (u->iobase + reg); +} + +#if 0 +static grub_uint32_t +grub_uhci_readreg32 (struct grub_uhci *u, grub_uhci_reg_t reg) +{ + return grub_inl (u->iobase + reg); +} +#endif + +static void +grub_uhci_writereg16 (struct grub_uhci *u, + grub_uhci_reg_t reg, grub_uint16_t val) +{ + grub_outw (val, u->iobase + reg); +} + +static void +grub_uhci_writereg32 (struct grub_uhci *u, + grub_uhci_reg_t reg, grub_uint32_t val) +{ + grub_outl (val, u->iobase + reg); +} + +static grub_err_t +grub_uhci_portstatus (grub_usb_controller_t dev, + unsigned int port, unsigned int enable); + + +/* Iterate over all PCI devices. Determine if a device is an UHCI + controller. If this is the case, initialize it. */ +static int grub_uhci_pci_iter (int bus, int device, int func, + grub_pci_id_t pciid __attribute__((unused))) +{ + grub_uint32_t class; + grub_uint32_t subclass; + grub_uint32_t base; + grub_uint32_t fp; + grub_pci_address_t addr; + struct grub_uhci *u; + int i; + + addr = grub_pci_make_address (bus, device, func, 2); + class = grub_pci_read (addr); + addr = grub_pci_make_address (bus, device, func, 2); + class = grub_pci_read (addr); + + subclass = (class >> 16) & 0xFF; + class >>= 24; + + /* If this is not an UHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03) + return 0; + + /* Determine IO base address. */ + addr = grub_pci_make_address (bus, device, func, 8); + base = grub_pci_read (addr); + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; + + /* Allocate memory for the controller and register it. */ + u = grub_malloc (sizeof (*u)); + if (! u) + return 1; + + u->next = uhci; + uhci = u; + u->iobase = base & GRUB_UHCI_IOMASK; + u->framelist = 0; + u->qh = 0; + u->td = 0; + grub_dprintf ("uhci", "class=0x%02x 0x%02x base=0x%x\n", + class, subclass, u->iobase); + + /* Reserve a page for the frame list. */ + u->framelist = grub_memalign (4096, 4096); + if (! u->framelist) + goto fail; + + /* The framelist pointer of UHCI is only 32 bits, make sure this + code works on on 64 bits architectures. */ +#if GRUB_CPU_SIZEOF_VOID_P == 8 + if ((grub_uint64_t) u->framelist >> 32) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "allocated frame list memory not <4GB"); + goto fail; + } +#endif + + /* The QH pointer of UHCI is only 32 bits, make sure this + code works on on 64 bits architectures. */ + u->qh = (grub_uhci_qh_t) grub_memalign (4096, 4096); + if (! u->qh) + goto fail; + +#if GRUB_CPU_SIZEOF_VOID_P == 8 + if ((grub_uint64_t) u->qh >> 32) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated QH memory not <4GB"); + goto fail; + } +#endif + + /* The TD pointer of UHCI is only 32 bits, make sure this + code works on on 64 bits architectures. */ + u->td = (grub_uhci_td_t) grub_memalign (4096, 4096*2); + if (! u->td) + goto fail; + +#if GRUB_CPU_SIZEOF_VOID_P == 8 + if ((grub_uint64_t) u->td >> 32) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "allocated TD memory not <4GB"); + goto fail; + } +#endif + + /* Link all Transfer Descriptors in a list of available Transfer + Descriptors. */ + for (i = 0; i < 256; i++) + u->td[i].linkptr = (grub_uint32_t) &u->td[i + 1]; + u->td[255 - 1].linkptr = 0; + u->tdfree = u->td; + + /* Make sure UHCI is disabled! */ + grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0); + + /* Setup the frame list pointers. Since no isochronous transfers + are and will be supported, they all point to the (same!) queue + head. */ + fp = (grub_uint32_t) u->qh & (~15); + /* Mark this as a queue head. */ + fp |= 2; + for (i = 0; i < 1024; i++) + u->framelist[i] = fp; + /* Program the framelist address into the UHCI controller. */ + grub_uhci_writereg32 (u, GRUB_UHCI_REG_FLBASEADD, + (grub_uint32_t) u->framelist); + + /* Make the Queue Heads point to eachother. */ + for (i = 0; i < 256; i++) + { + /* Point to the next QH. */ + u->qh[i].linkptr = (grub_uint32_t) (&u->qh[i + 1]) & (~15); + + /* This is a QH. */ + u->qh[i].linkptr |= GRUB_UHCI_LINK_QUEUE_HEAD; + + /* For the moment, do not point to a Transfer Descriptor. These + are set at transfer time, so just terminate it. */ + u->qh[i].elinkptr = 1; + } + + /* The last Queue Head should terminate. 256 are too many QHs so + just use 50. */ + u->qh[50 - 1].linkptr = 1; + + /* Enable UHCI again. */ + grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7)); + + /* UHCI is initialized and ready for transfers. */ + grub_dprintf ("uhci", "UHCI initialized\n"); + + +#if 0 + { + int i; + for (i = 0; i < 10; i++) + { + grub_uint16_t frnum; + + frnum = grub_uhci_readreg16 (u, 6); + grub_dprintf ("uhci", "Framenum=%d\n", frnum); + grub_millisleep (100); + } + } +#endif + + return 0; + + fail: + if (u) + { + grub_free ((void *) u->qh); + grub_free (u->framelist); + } + grub_free (u); + + return 1; +} + +static void +grub_uhci_inithw (void) +{ + grub_pci_iterate (grub_uhci_pci_iter); +} + +static grub_uhci_td_t +grub_alloc_td (struct grub_uhci *u) +{ + grub_uhci_td_t ret; + + /* Check if there is a Transfer Descriptor available. */ + if (! u->tdfree) + return NULL; + + ret = u->tdfree; + u->tdfree = (grub_uhci_td_t) u->tdfree->linkptr; + + return ret; +} + +static void +grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) +{ + td->linkptr = (grub_uint32_t) u->tdfree; + u->tdfree = td; +} + +static void +grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td) +{ + /* Free the TDs in this queue. */ + while (td) + { + grub_uhci_td_t tdprev; + + /* Unlink the queue. */ + tdprev = td; + td = (grub_uhci_td_t) td->linkptr2; + + /* Free the TD. */ + grub_free_td (u, tdprev); + } +} + +static grub_uhci_qh_t +grub_alloc_qh (struct grub_uhci *u, + grub_transaction_type_t tr __attribute__((unused))) +{ + int i; + grub_uhci_qh_t qh; + + /* Look for a Queue Head for this transfer. Skip the first QH if + this is a Interrupt Transfer. */ +#if 0 + if (tr == GRUB_USB_TRANSACTION_TYPE_INTERRUPT) + i = 0; + else +#endif + i = 1; + + for (; i < 255; i++) + { + if (u->qh[i].elinkptr & 1) + break; + } + qh = &u->qh[i]; + if (! (qh->elinkptr & 1)) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "no free queue heads available"); + return NULL; + } + + return qh; +} + +static grub_uhci_td_t +grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, + grub_transfer_type_t type, unsigned int addr, + unsigned int toggle, grub_size_t size, + char *data) +{ + grub_uhci_td_t td; + static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; + + /* XXX: Check if data is <4GB. If it isn't, just copy stuff around. + This is only relevant for 64 bits architectures. */ + + /* Grab a free Transfer Descriptor and initialize it. */ + td = grub_alloc_td (u); + if (! td) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "no transfer descriptors available for UHCI transfer"); + return 0; + } + + grub_dprintf ("uhci", + "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", + endp, type, addr, toggle, size, data, td); + + /* Don't point to any TD, just terminate. */ + td->linkptr = 1; + + /* Active! Only retry a transfer 3 times. */ + td->ctrl_status = (1 << 23) | (3 << 27); + + /* If zero bytes are transmitted, size is 0x7FF. Otherwise size is + size-1. */ + if (size == 0) + size = 0x7FF; + else + size = size - 1; + + /* Setup whatever is required for the token packet. */ + td->token = ((size << 21) | (toggle << 19) | (endp << 15) + | (addr << 8) | tf[type]); + + td->buffer = (grub_uint32_t) data; + + return td; +} + +static grub_usb_err_t +grub_uhci_transfer (grub_usb_controller_t dev, + grub_usb_transfer_t transfer) +{ + struct grub_uhci *u = (struct grub_uhci *) dev->data; + grub_uhci_qh_t qh; + grub_uhci_td_t td; + grub_uhci_td_t td_first = NULL; + grub_uhci_td_t td_prev = NULL; + grub_usb_err_t err = GRUB_USB_ERR_NONE; + int i; + + /* Allocate a queue head for the transfer queue. */ + qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL); + if (! qh) + return grub_errno; + + for (i = 0; i < transfer->transcnt; i++) + { + grub_usb_transaction_t tr = &transfer->transactions[i]; + + td = grub_uhci_transaction (u, transfer->endpoint, tr->pid, + transfer->devaddr, tr->toggle, + tr->size, tr->data); + if (! td) + { + /* Terminate and free. */ + td_prev->linkptr2 = 0; + td_prev->linkptr = 1; + + if (td_first) + grub_free_queue (u, td_first); + + return GRUB_USB_ERR_INTERNAL; + } + + if (! td_first) + td_first = td; + else + { + td_prev->linkptr2 = (grub_uint32_t) td; + td_prev->linkptr = (grub_uint32_t) td; + td_prev->linkptr |= 4; + } + td_prev = td; + } + td_prev->linkptr2 = 0; + td_prev->linkptr = 1; + + grub_dprintf ("uhci", "setup transaction %d\n", transfer->type); + + /* Link it into the queue and terminate. Now the transaction can + take place. */ + qh->elinkptr = (grub_uint32_t) td_first; + + grub_dprintf ("uhci", "initiate transaction\n"); + + /* Wait until either the transaction completed or an error + occured. */ + for (;;) + { + grub_uhci_td_t errtd; + + errtd = (grub_uhci_td_t) (qh->elinkptr & ~0x0f); + + grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n", + errtd->ctrl_status, errtd->buffer & (~15), errtd); + + /* Check if the transaction completed. */ + if (qh->elinkptr & 1) + break; + + grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status); + + /* Check if the TD is not longer active. */ + if (! (errtd->ctrl_status & (1 << 23))) + { + grub_dprintf ("uhci", ">>t status=0x%02x\n", errtd->ctrl_status); + + /* Check if the endpoint is stalled. */ + if (errtd->ctrl_status & (1 << 22)) + err = GRUB_USB_ERR_STALL; + + /* Check if an error related to the data buffer occured. */ + if (errtd->ctrl_status & (1 << 21)) + err = GRUB_USB_ERR_DATA; + + /* Check if a babble error occured. */ + if (errtd->ctrl_status & (1 << 20)) + err = GRUB_USB_ERR_BABBLE; + + /* Check if a NAK occured. */ + if (errtd->ctrl_status & (1 << 19)) + err = GRUB_USB_ERR_NAK; + + /* Check if a timeout occured. */ + if (errtd->ctrl_status & (1 << 18)) + err = GRUB_USB_ERR_TIMEOUT; + + /* Check if a bitstuff error occured. */ + if (errtd->ctrl_status & (1 << 17)) + err = GRUB_USB_ERR_BITSTUFF; + + if (err) + goto fail; + + /* Fall through, no errors occured, so the QH might be + updated. */ + grub_dprintf ("uhci", "transaction fallthrough\n"); + } + } + + grub_dprintf ("uhci", "transaction complete\n"); + + fail: + + grub_dprintf ("uhci", "transaction failed\n"); + + /* Place the QH back in the free list and deallocate the associated + TDs. */ + qh->elinkptr = 1; + grub_free_queue (u, td_first); + + return err; +} + +static int +grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev)) +{ + struct grub_uhci *u; + struct grub_usb_controller dev; + + for (u = uhci; u; u = u->next) + { + dev.data = u; + if (hook (&dev)) + return 1; + } + + return 0; +} + +static grub_err_t +grub_uhci_portstatus (grub_usb_controller_t dev, + unsigned int port, unsigned int enable) +{ + struct grub_uhci *u = (struct grub_uhci *) dev->data; + int reg; + unsigned int status; + + grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); + + if (port == 0) + reg = GRUB_UHCI_REG_PORTSC1; + else if (port == 1) + reg = GRUB_UHCI_REG_PORTSC2; + else + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "UHCI Root Hub port does not exist"); + + status = grub_uhci_readreg16 (u, reg); + grub_dprintf ("uhci", "detect=0x%02x\n", status); + + /* Reset the port. */ + grub_uhci_writereg16 (u, reg, enable << 9); + + /* Wait for the reset to complete. XXX: How long exactly? */ + grub_millisleep (10); + status = grub_uhci_readreg16 (u, reg); + grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); + grub_dprintf ("uhci", "reset completed\n"); + + /* Enable the port. */ + grub_uhci_writereg16 (u, reg, enable << 2); + grub_millisleep (10); + + grub_dprintf ("uhci", "waiting for the port to be enabled\n"); + + while (! (grub_uhci_readreg16 (u, reg) & (1 << 2))); + + status = grub_uhci_readreg16 (u, reg); + grub_dprintf ("uhci", ">3detect=0x%02x\n", status); + + + return GRUB_ERR_NONE; +} + +static grub_usb_speed_t +grub_uhci_detect_dev (grub_usb_controller_t dev, int port) +{ + struct grub_uhci *u = (struct grub_uhci *) dev->data; + int reg; + unsigned int status; + + if (port == 0) + reg = GRUB_UHCI_REG_PORTSC1; + else if (port == 1) + reg = GRUB_UHCI_REG_PORTSC2; + else + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "UHCI Root Hub port does not exist"); + + status = grub_uhci_readreg16 (u, reg); + + grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port); + + if (! (status & 1)) + return GRUB_USB_SPEED_NONE; + else if (status & (1 << 8)) + return GRUB_USB_SPEED_LOW; + else + return GRUB_USB_SPEED_FULL; +} + +static int +grub_uhci_hubports (grub_usb_controller_t dev __attribute__((unused))) +{ + /* The root hub has exactly two ports. */ + return 2; +} + + +static struct grub_usb_controller_dev usb_controller = +{ + .name = "uhci", + .iterate = grub_uhci_iterate, + .transfer = grub_uhci_transfer, + .hubports = grub_uhci_hubports, + .portstatus = grub_uhci_portstatus, + .detect_dev = grub_uhci_detect_dev +}; + +GRUB_MOD_INIT(uhci) +{ + grub_uhci_inithw (); + grub_usb_controller_dev_register (&usb_controller); + grub_dprintf ("uhci", "registed\n"); +} + +GRUB_MOD_FINI(uhci) +{ + struct grub_uhci *u; + + /* Disable all UHCI controllers. */ + for (u = uhci; u; u = u->next) + grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 0); + + /* Unregister the controller. */ + grub_usb_controller_dev_unregister (&usb_controller); +} diff --git a/bus/usb/usb.c b/bus/usb/usb.c new file mode 100644 index 0000000..a30598f --- /dev/null +++ b/bus/usb/usb.c @@ -0,0 +1,263 @@ +/* usb.c - Generic USB interfaces. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_usb_controller_dev_t grub_usb_list; + +void +grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) +{ + auto int iterate_hook (grub_usb_controller_t dev); + + /* Iterate over all controllers found by the driver. */ + int iterate_hook (grub_usb_controller_t dev) + { + dev->dev = usb; + + /* Enable the ports of the USB Root Hub. */ + grub_usb_root_hub (dev); + + return 0; + } + + usb->next = grub_usb_list; + grub_usb_list = usb; + + if (usb->iterate) + usb->iterate (iterate_hook); +} + +void +grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb) +{ + grub_usb_controller_dev_t *p, q; + + for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next) + if (q == usb) + { + *p = q->next; + break; + } +} + +#if 0 +int +grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev)) +{ + grub_usb_controller_dev_t p; + + auto int iterate_hook (grub_usb_controller_t dev); + + int iterate_hook (grub_usb_controller_t dev) + { + dev->dev = p; + if (hook (dev)) + return 1; + return 0; + } + + /* Iterate over all controller drivers. */ + for (p = grub_usb_list; p; p = p->next) + { + /* Iterate over the busses of the controllers. XXX: Actually, a + hub driver should do this. */ + if (p->iterate (iterate_hook)) + return 1; + } + + return 0; +} +#endif + + +grub_usb_err_t +grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) +{ + dev->toggle[endpoint] = 0; + return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_STANDARD + | GRUB_USB_REQTYPE_TARGET_ENDP), + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_FEATURE_ENDP_HALT, + endpoint, 0, 0); +} + +grub_usb_err_t +grub_usb_set_configuration (grub_usb_device_t dev, int configuration) +{ + int i; + + for (i = 0; i < 16; i++) + dev->toggle[i] = 0; + + return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_STANDARD + | GRUB_USB_REQTYPE_TARGET_DEV), + GRUB_USB_REQ_SET_CONFIGURATION, configuration, + 0, 0, NULL); +} + +grub_usb_err_t +grub_usb_get_descriptor (grub_usb_device_t dev, + grub_uint8_t type, grub_uint8_t index, + grub_size_t size, char *data) +{ + return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN + | GRUB_USB_REQTYPE_STANDARD + | GRUB_USB_REQTYPE_TARGET_DEV), + GRUB_USB_REQ_GET_DESCRIPTOR, + (type << 8) | index, + 0, size, data); +} + +struct grub_usb_desc_endp * +grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr) +{ + int i; + + for (i = 0; i < usbdev->config[0].descconf->numif; i++) + { + struct grub_usb_desc_if *interf; + int j; + + interf = usbdev->config[0].interf[i].descif; + + for (j = 0; j < interf->endpointcnt; j++) + { + struct grub_usb_desc_endp *endp; + endp = &usbdev->config[0].interf[i].descendp[j]; + + if (endp->endp_addr == addr) + return endp; + } + } + + return NULL; +} + +grub_usb_err_t +grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, + char **string) +{ + struct grub_usb_desc_str descstr; + struct grub_usb_desc_str *descstrp; + grub_usb_err_t err; + + /* Only get the length. */ + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, 1, (char *) &descstr); + if (err) + return err; + + descstrp = grub_malloc (descstr.length); + if (! descstrp) + return GRUB_USB_ERR_INTERNAL; + err = grub_usb_control_msg (dev, 1 << 7, + 0x06, (3 << 8) | index, + langid, descstr.length, (char *) descstrp); + + *string = grub_malloc (descstr.length / 2); + if (! *string) + { + grub_free (descstrp); + return GRUB_USB_ERR_INTERNAL; + } + + grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); + (*string)[descstr.length / 2 - 1] = '\0'; + grub_free (descstrp); + + return GRUB_USB_ERR_NONE; +} + +grub_usb_err_t +grub_usb_device_initialize (grub_usb_device_t dev) +{ + struct grub_usb_desc_device *descdev; + struct grub_usb_desc_config config; + grub_usb_err_t err; + int i; + + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, + 0, sizeof (struct grub_usb_desc_device), + (char *) &dev->descdev); + if (err) + return err; + descdev = &dev->descdev; + + for (i = 0; i < 8; i++) + dev->config[i].descconf = NULL; + + for (i = 0; i < descdev->configcnt; i++) + { + int pos; + int currif; + char *data; + + /* First just read the first 4 bytes of the configuration + descriptor, after that it is known how many bytes really have + to be read. */ + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4, + (char *) &config); + + data = grub_malloc (config.totallen); + if (! data) + { + err = GRUB_USB_ERR_INTERNAL; + goto fail; + } + + dev->config[i].descconf = (struct grub_usb_desc_config *) data; + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, + config.totallen, data); + if (err) + goto fail; + + /* Skip the configuration descriptor. */ + pos = sizeof (struct grub_usb_desc_config); + + /* Read all interfaces. */ + for (currif = 0; currif < dev->config[i].descconf->numif; currif++) + { + dev->config[i].interf[currif].descif + = (struct grub_usb_desc_if *) &data[pos]; + pos += sizeof (struct grub_usb_desc_if); + + /* Point to the first endpoint. */ + dev->config[i].interf[currif].descendp + = (struct grub_usb_desc_endp *) &data[pos]; + pos += (sizeof (struct grub_usb_desc_endp) + * dev->config[i].interf[currif].descif->endpointcnt); + } + } + + return GRUB_USB_ERR_NONE; + + fail: + + for (i = 0; i < 8; i++) + grub_free (dev->config[i].descconf); + + return err; +} diff --git a/bus/usb/usbhub.c b/bus/usb/usbhub.c new file mode 100644 index 0000000..ba0925a --- /dev/null +++ b/bus/usb/usbhub.c @@ -0,0 +1,193 @@ +/* usb.c - USB Hub Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* USB Supports 127 devices, with device 0 as special case. */ +static struct grub_usb_device *grub_usb_devs[128]; + +/* Add a device that currently has device number 0 and resides on + CONTROLLER, the Hub reported that the device speed is SPEED. */ +static grub_usb_device_t +grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_usb_speed_t speed) +{ + grub_usb_device_t dev; + int i; + + dev = grub_malloc (sizeof (struct grub_usb_device)); + if (! dev) + return NULL; + + dev->controller = *controller; + dev->addr = 0; + dev->initialized = 0; + dev->speed = speed; + + grub_usb_device_initialize (dev); + + /* Assign a new address to the device. */ + for (i = 1; i < 128; i++) + { + if (! grub_usb_devs[i]) + break; + } + if (grub_usb_devs[i]) + { + grub_error (GRUB_ERR_IO, "Can't assign address to USB device"); + return NULL; + } + + grub_usb_control_msg (dev, + (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_STANDARD + | GRUB_USB_REQTYPE_TARGET_DEV), + GRUB_USB_REQ_SET_ADDRESS, + i, 0, 0, NULL); + dev->addr = i; + dev->initialized = 1; + grub_usb_devs[i] = dev; + + return dev; +} + + +static grub_err_t +grub_usb_add_hub (grub_usb_device_t dev) +{ + struct grub_usb_usb_hubdesc hubdesc; + grub_err_t err; + int i; + + grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_DEV), + GRUB_USB_REQ_GET_DESCRIPTOR, + (GRUB_USB_DESCRIPTOR_HUB << 8) | 0, + 0, sizeof (hubdesc), (char *) &hubdesc); + + /* Iterate over the Hub ports. */ + for (i = 1; i <= hubdesc.portcnt; i++) + { + grub_uint32_t status; + + /* Get the port status. */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + GRUB_USB_REQ_HUB_GET_PORT_STATUS, + 0, i, sizeof (status), (char *) &status); + + /* Just ignore the device if the Hub does not report the + status. */ + if (err) + continue; + + /* If connected, reset and enable the port. */ + if (status & GRUB_USB_HUB_STATUS_CONNECTED) + { + grub_usb_speed_t speed; + + /* Determine the device speed. */ + if (status & GRUB_USB_HUB_STATUS_LOWSPEED) + speed = GRUB_USB_SPEED_LOW; + else + { + if (status & GRUB_USB_HUB_STATUS_HIGHSPEED) + speed = GRUB_USB_SPEED_HIGH; + else + speed = GRUB_USB_SPEED_FULL; + } + + /* A device is actually connected to this port, not enable + the port. XXX: Why 0x03? According to some docs it + should be 0x0. Check the specification! */ + err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT + | GRUB_USB_REQTYPE_CLASS + | GRUB_USB_REQTYPE_TARGET_OTHER), + 0x3, 0x4, i, 0, 0); + + /* If the Hub does not cooperate for this port, just skip + the port. */ + if (err) + continue; + + /* Add the device and assign a device address to it. */ + grub_usb_hub_add_dev (&dev->controller, speed); + } + } + + return GRUB_ERR_NONE; +} + +grub_usb_err_t +grub_usb_root_hub (grub_usb_controller_t controller) +{ + grub_err_t err; + int ports; + int i; + + /* Query the number of ports the root Hub has. */ + ports = controller->dev->hubports (controller); + + for (i = 0; i < ports; i++) + { + grub_usb_speed_t speed = controller->dev->detect_dev (controller, i); + + if (speed != GRUB_USB_SPEED_NONE) + { + grub_usb_device_t dev; + + /* Enable the port. */ + err = controller->dev->portstatus (controller, i, 1); + if (err) + continue; + + /* Enable the port and create a device. */ + dev = grub_usb_hub_add_dev (controller, speed); + if (! dev) + continue; + + /* If the device is a Hub, scan it for more devices. */ + if (dev->descdev.class == 0x09) + grub_usb_add_hub (dev); + } + } + + return GRUB_USB_ERR_NONE; +} + +int +grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) +{ + int i; + + for (i = 0; i < 128; i++) + { + if (grub_usb_devs[i]) + { + if (hook (grub_usb_devs[i])) + return 1; + } + } + + return 0; +} diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c new file mode 100644 index 0000000..8b2d5ad --- /dev/null +++ b/bus/usb/usbtrans.c @@ -0,0 +1,212 @@ +/* usbtrans.c - USB Transfers and Transactions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +grub_usb_err_t +grub_usb_control_msg (grub_usb_device_t dev, + grub_uint8_t reqtype, + grub_uint8_t request, + grub_uint16_t value, + grub_uint16_t index, + grub_size_t size, char *data) +{ + int i; + grub_usb_transfer_t transfer; + int datablocks; + struct grub_usb_packet_setup setupdata; + grub_usb_err_t err; + int max; + + grub_dprintf ("usb", + "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n", + reqtype, request, value, index, size); + + /* Create a transfer. */ + transfer = grub_malloc (sizeof (struct grub_usb_transfer)); + if (! transfer) + return grub_errno; + + /* Determine the maximum packet size. */ + if (dev->initialized) + max = dev->descdev.maxsize0; + else + max = 64; + + datablocks = (size + max - 1) / max; + + /* XXX: Discriminate between different types of control + messages. */ + transfer->transcnt = datablocks + 2; + transfer->size = size; /* XXX ? */ + transfer->endpoint = 0; + transfer->devaddr = dev->addr; + transfer->type = GRUB_USB_TRANSACTION_TYPE_CONTROL; + transfer->max = max; + transfer->dev = dev; + + /* Allocate an array of transfer data structures. */ + transfer->transactions = grub_malloc (transfer->transcnt + * sizeof (struct grub_usb_transfer)); + if (! transfer->transactions) + { + grub_free (transfer); + return grub_errno; + } + + /* Build a Setup packet. XXX: Endianess. */ + setupdata.reqtype = reqtype; + setupdata.request = request; + setupdata.value = value; + setupdata.index = index; + setupdata.length = size; + transfer->transactions[0].size = sizeof (setupdata); + transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; + transfer->transactions[0].data = (char *) &setupdata; + transfer->transactions[0].toggle = 0; + + /* Now the data... XXX: Is this the right way to transfer control + transfers? */ + for (i = 0; i < datablocks; i++) + { + grub_usb_transaction_t tr = &transfer->transactions[i + 1]; + + tr->size = (size > max) ? max : size; + /* Use the right most bit as the data toggle. Simple and + effective. */ + tr->toggle = !(i & 1); + if (reqtype & 128) + tr->pid = GRUB_USB_TRANSFER_TYPE_IN; + else + tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; + tr->data = &data[i * max]; + size -= max; + } + + /* End with an empty OUT transaction. */ + transfer->transactions[datablocks + 1].size = 0; + transfer->transactions[datablocks + 1].data = NULL; + if (reqtype & 128) + transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; + else + transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN; + + transfer->transactions[datablocks + 1].toggle = 1; + + err = dev->controller.dev->transfer (&dev->controller, transfer); + + grub_free (transfer->transactions); + grub_free (transfer); + + return err; +} + +static grub_usb_err_t +grub_usb_bulk_readwrite (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data, + grub_transfer_type_t type) +{ + int i; + grub_usb_transfer_t transfer; + int datablocks; + unsigned int max; + grub_usb_err_t err; + int toggle = dev->toggle[endpoint]; + + /* Use the maximum packet size given in the endpoint descriptor. */ + if (dev->initialized) + { + struct grub_usb_desc_endp *endpdesc; + endpdesc = grub_usb_get_endpdescriptor (dev, 0); + + if (endpdesc) + max = endpdesc->maxpacket; + else + max = 64; + } + else + max = 64; + + /* Create a transfer. */ + transfer = grub_malloc (sizeof (struct grub_usb_transfer)); + if (! transfer) + return grub_errno; + + datablocks = ((size + max - 1) / max); + transfer->transcnt = datablocks; + transfer->size = size - 1; + transfer->endpoint = endpoint; + transfer->devaddr = dev->addr; + transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; + transfer->max = max; + transfer->dev = dev; + + /* Allocate an array of transfer data structures. */ + transfer->transactions = grub_malloc (transfer->transcnt + * sizeof (struct grub_usb_transfer)); + if (! transfer->transactions) + { + grub_free (transfer); + return grub_errno; + } + + /* Set up all transfers. */ + for (i = 0; i < datablocks; i++) + { + grub_usb_transaction_t tr = &transfer->transactions[i]; + + tr->size = (size > max) ? max : size; + /* XXX: Use the right most bit as the data toggle. Simple and + effective. */ + tr->toggle = toggle; + toggle = toggle ? 0 : 1; + tr->pid = type; + tr->data = &data[i * max]; + size -= tr->size; + } + + err = dev->controller.dev->transfer (&dev->controller, transfer); + grub_dprintf ("usb", "toggle=%d\n", toggle); + dev->toggle[endpoint] = toggle; + + grub_free (transfer->transactions); + grub_free (transfer); + + return err; +} + +grub_usb_err_t +grub_usb_bulk_write (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data) +{ + return grub_usb_bulk_readwrite (dev, endpoint, size, data, + GRUB_USB_TRANSFER_TYPE_OUT); +} + +grub_usb_err_t +grub_usb_bulk_read (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data) +{ + return grub_usb_bulk_readwrite (dev, endpoint, size, data, + GRUB_USB_TRANSFER_TYPE_IN); +} diff --git a/commands/blocklist.c b/commands/blocklist.c new file mode 100644 index 0000000..c797a5f --- /dev/null +++ b/commands/blocklist.c @@ -0,0 +1,122 @@ +/* blocklist.c - print the block list of a file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_blocklist (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_file_t file; + char buf[GRUB_DISK_SECTOR_SIZE]; + unsigned long start_sector = 0; + unsigned num_sectors = 0; + int num_entries = 0; + grub_disk_addr_t part_start = 0; + auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset, + unsigned length); + auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num, + unsigned offset, unsigned length); + + void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset, + unsigned length) + { + if (num_sectors > 0) + { + if (start_sector + num_sectors == sector + && offset == 0 && length == GRUB_DISK_SECTOR_SIZE) + { + num_sectors++; + return; + } + + print_blocklist (start_sector, num_sectors, 0, 0); + num_sectors = 0; + } + + if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE) + { + start_sector = sector; + num_sectors++; + } + else + print_blocklist (sector, 0, offset, length); + } + + void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num, + unsigned offset, unsigned length) + { + if (num_entries++) + grub_printf (","); + + grub_printf ("%llu", (unsigned long long) (sector - part_start)); + if (num > 0) + grub_printf ("+%u", num); + if (offset != 0 || length != 0) + grub_printf ("[%u-%u]", offset, offset + length); + } + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + + file = grub_file_open (args[0]); + if (! file) + return grub_errno; + + if (! file->device->disk) + return grub_error (GRUB_ERR_BAD_DEVICE, + "this command is available only for disk devices."); + + if (file->device->disk->partition) + part_start = grub_partition_get_start (file->device->disk->partition); + + file->read_hook = read_blocklist; + + while (grub_file_read (file, buf, sizeof (buf)) > 0) + ; + + if (num_sectors > 0) + print_blocklist (start_sector, num_sectors, 0, 0); + + grub_file_close (file); + + return grub_errno; +} + + +GRUB_MOD_INIT(blocklist) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("blocklist", grub_cmd_blocklist, + GRUB_COMMAND_FLAG_BOTH, + "blocklist FILE", + "Print a block list.", 0); +} + +GRUB_MOD_FINI(blocklist) +{ + grub_unregister_command ("blocklist"); +} diff --git a/commands/boot.c b/commands/boot.c new file mode 100644 index 0000000..e24a3a4 --- /dev/null +++ b/commands/boot.c @@ -0,0 +1,50 @@ +/* boot.c - command to boot an operating system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_boot (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args __attribute__ ((unused))) +{ + if (argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments"); + + grub_loader_boot (); + + return 0; +} + + + +GRUB_MOD_INIT(boot) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("boot", grub_cmd_boot, GRUB_COMMAND_FLAG_BOTH, + "boot", "Boot an operating system.", 0); +} + +GRUB_MOD_FINI(boot) +{ + grub_unregister_command ("boot"); +} diff --git a/commands/cat.c b/commands/cat.c new file mode 100644 index 0000000..b5dda4d --- /dev/null +++ b/commands/cat.c @@ -0,0 +1,88 @@ +/* cat.c - command to show the contents of a file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_cat (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) + +{ + grub_file_t file; + char buf[GRUB_DISK_SECTOR_SIZE]; + grub_ssize_t size; + int key = 0; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + file = grub_gzfile_open (args[0], 1); + if (! file) + return 0; + + while ((size = grub_file_read (file, buf, sizeof (buf))) > 0 + && key != GRUB_TERM_ESC) + { + int i; + + for (i = 0; i < size; i++) + { + unsigned char c = buf[i]; + + if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') + grub_putchar (c); + else + { + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("<%x>", (int) c); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + } + } + + while (grub_checkkey () >= 0 && + (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC) + ; + } + + grub_putchar ('\n'); + grub_refresh (); + grub_file_close (file); + + return 0; +} + + +GRUB_MOD_INIT(cat) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("cat", grub_cmd_cat, GRUB_COMMAND_FLAG_BOTH, + "cat FILE", "Show the contents of a file.", 0); +} + +GRUB_MOD_FINI(cat) +{ + grub_unregister_command ("cat"); +} diff --git a/commands/cmp.c b/commands/cmp.c new file mode 100644 index 0000000..87620b6 --- /dev/null +++ b/commands/cmp.c @@ -0,0 +1,119 @@ +/* cmd.c - command to cmp an operating system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BUFFER_SIZE 512 + +static grub_err_t +grub_cmd_cmp (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_ssize_t rd1, rd2; + grub_off_t pos; + grub_file_t file1 = 0; + grub_file_t file2 = 0; + char *buf1 = 0; + char *buf2 = 0; + + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); + + grub_printf ("Compare `%s' and `%s':\n", args[0], + args[1]); + + file1 = grub_gzfile_open (args[0], 1); + file2 = grub_gzfile_open (args[1], 1); + if (! file1 || ! file2) + goto cleanup; + + if (grub_file_size (file1) != grub_file_size (file2)) + grub_printf ("Differ in size: %llu [%s], %llu [%s]\n", + (unsigned long long) grub_file_size (file1), args[0], + (unsigned long long) grub_file_size (file2), args[1]); + else + { + pos = 0; + + buf1 = grub_malloc (BUFFER_SIZE); + buf2 = grub_malloc (BUFFER_SIZE); + + if (! buf1 || ! buf2) + goto cleanup; + + do + { + int i; + + rd1 = grub_file_read (file1, buf1, BUFFER_SIZE); + rd2 = grub_file_read (file2, buf2, BUFFER_SIZE); + + if (rd1 != rd2) + goto cleanup; + + for (i = 0; i < rd2; i++) + { + if (buf1[i] != buf2[i]) + { + grub_printf ("Differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n", + (unsigned long long) (i + pos), buf1[i], args[0], + buf2[i], args[1]); + goto cleanup; + } + } + pos += BUFFER_SIZE; + + } + while (rd2); + + grub_printf ("The files are identical.\n"); + } + +cleanup: + + if (buf1) + grub_free (buf1); + if (buf2) + grub_free (buf2); + if (file1) + grub_file_close (file1); + if (file2) + grub_file_close (file2); + + return grub_errno; +} + + +GRUB_MOD_INIT(cmp) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("cmp", grub_cmd_cmp, GRUB_COMMAND_FLAG_BOTH, + "cmp FILE1 FILE2", "Compare two files.", 0); +} + +GRUB_MOD_FINI(cmp) +{ + grub_unregister_command ("cmp"); +} diff --git a/commands/configfile.c b/commands/configfile.c new file mode 100644 index 0000000..2d1fb67 --- /dev/null +++ b/commands/configfile.c @@ -0,0 +1,78 @@ +/* configfile.c - command to manually load config file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_configfile (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) + +{ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_cls (); + grub_env_context_open (); + grub_normal_execute (args[0], 1); + grub_env_context_close (); + + return 0; +} + +static grub_err_t +grub_cmd_source (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) + +{ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_normal_execute (args[0], 1); + + return 0; +} + + +GRUB_MOD_INIT(configfile) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("configfile", grub_cmd_configfile, + GRUB_COMMAND_FLAG_BOTH, "configfile FILE", + "Load another config file.", 0); + grub_register_command ("source", grub_cmd_source, + GRUB_COMMAND_FLAG_BOTH, "source FILE", + "Load another config file without changing context.", + 0); + grub_register_command (".", grub_cmd_source, + GRUB_COMMAND_FLAG_BOTH, ". FILE", + "Load another config file without changing context.", + 0); +} + +GRUB_MOD_FINI(configfile) +{ + grub_unregister_command ("configfile"); + grub_unregister_command ("source"); + grub_unregister_command ("."); +} diff --git a/commands/crc.c b/commands/crc.c new file mode 100644 index 0000000..5148648 --- /dev/null +++ b/commands/crc.c @@ -0,0 +1,66 @@ +/* crc.c - command to calculate the crc32 checksum of a file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_crc (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) + +{ + grub_file_t file; + char buf[GRUB_DISK_SECTOR_SIZE]; + grub_ssize_t size; + grub_uint32_t crc; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + file = grub_file_open (args[0]); + if (! file) + return 0; + + crc = 0; + while ((size = grub_file_read (file, buf, sizeof (buf))) > 0) + crc = grub_getcrc32 (crc, buf, size); + + grub_file_close (file); + + grub_printf ("%08x\n", crc); + + return 0; +} + +GRUB_MOD_INIT(crc) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("crc", grub_cmd_crc, GRUB_COMMAND_FLAG_BOTH, + "crc FILE", "Calculate the crc32 checksum of a file.", 0); +} + +GRUB_MOD_FINI(crc) +{ + grub_unregister_command ("crc"); +} diff --git a/commands/date.c b/commands/date.c new file mode 100644 index 0000000..2331918 --- /dev/null +++ b/commands/date.c @@ -0,0 +1,145 @@ +/* date.c - command to display/set current datetime. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define GRUB_DATETIME_SET_YEAR 1 +#define GRUB_DATETIME_SET_MONTH 2 +#define GRUB_DATETIME_SET_DAY 4 +#define GRUB_DATETIME_SET_HOUR 8 +#define GRUB_DATETIME_SET_MINUTE 16 +#define GRUB_DATETIME_SET_SECOND 32 + +static grub_err_t +grub_cmd_date (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_datetime datetime; + int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}}; + int value[6], mask; + + if (argc == 0) + { + if (grub_get_datetime (&datetime)) + return grub_errno; + + grub_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n", + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, datetime.second, + grub_get_weekday_name (&datetime)); + + return 0; + } + + grub_memset (&value, 0, sizeof (value)); + mask = 0; + + for (; argc; argc--, args++) + { + char *p, c; + int m1, ofs, n, cur_mask; + + p = args[0]; + m1 = grub_strtoul (p, &p, 10); + + c = *p; + if (c == '-') + ofs = 0; + else if (c == ':') + ofs = 3; + else + goto fail; + + value[ofs] = m1; + cur_mask = (1 << ofs); + mask &= ~(cur_mask * (1 + 2 + 4)); + + for (n = 1; (n < 3) && (*p); n++) + { + if (*p != c) + goto fail; + + value[ofs + n] = grub_strtoul (p + 1, &p, 10); + cur_mask |= (1 << (ofs + n)); + } + + if (*p) + goto fail; + + if ((ofs == 0) && (n == 2)) + { + value[ofs + 2] = value[ofs + 1]; + value[ofs + 1] = value[ofs]; + ofs++; + cur_mask <<= 1; + } + + for (; n; n--, ofs++) + if ((value [ofs] < limit[ofs][0]) || + (value [ofs] > limit[ofs][1])) + goto fail; + + mask |= cur_mask; + } + + if (grub_get_datetime (&datetime)) + return grub_errno; + + if (mask & GRUB_DATETIME_SET_YEAR) + datetime.year = value[0]; + + if (mask & GRUB_DATETIME_SET_MONTH) + datetime.month = value[1]; + + if (mask & GRUB_DATETIME_SET_DAY) + datetime.day = value[2]; + + if (mask & GRUB_DATETIME_SET_HOUR) + datetime.hour = value[3]; + + if (mask & GRUB_DATETIME_SET_MINUTE) + datetime.minute = value[4]; + + if (mask & GRUB_DATETIME_SET_SECOND) + datetime.second = value[5]; + + return grub_set_datetime (&datetime); + +fail: + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid datetime"); +} + +GRUB_MOD_INIT(date) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("date", grub_cmd_date, + GRUB_COMMAND_FLAG_BOTH, + "date [[year-]month-day] [hour:minute[:second]]", + "Command to display/set current datetime.", 0); +} + +GRUB_MOD_FINI(date) +{ + grub_unregister_command ("date"); +} diff --git a/commands/echo.c b/commands/echo.c new file mode 100644 index 0000000..e2a483c --- /dev/null +++ b/commands/echo.c @@ -0,0 +1,124 @@ +/* echo.c - Command to display a line of text */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {0, 'n', 0, "do not output the trailing newline", 0, 0}, + {0, 'e', 0, "enable interpretation of backslash escapes", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + + +static grub_err_t +grub_cmd_echo (struct grub_arg_list *state, int argc, char **args) +{ + int newline = 1; + int i; + + /* Check if `-n' was used. */ + if (state[0].set) + newline = 0; + + for (i = 0; i < argc; i++) + { + char *arg = *args; + args++; + + while (*arg) + { + /* In case `-e' is used, parse backslashes. */ + if (*arg == '\\' && state[1].set) + { + arg++; + if (*arg == '\0') + break; + + switch (*arg) + { + case '\\': + grub_printf ("\\"); + break; + + case 'a': + grub_printf ("\a"); + break; + + case 'c': + newline = 0; + break; + + case 'f': + grub_printf ("\f"); + break; + + case 'n': + grub_printf ("\n"); + break; + + case 'r': + grub_printf ("\r"); + break; + + case 't': + grub_printf ("\t"); + break; + + case 'v': + grub_printf ("\v"); + break; + } + arg++; + continue; + } + + /* This was not an escaped character, or escaping is not + enabled. */ + grub_printf ("%c", *arg); + arg++; + } + + /* If another argument follows, insert a space. */ + if (i != argc - 1) + grub_printf (" " ); + } + + if (newline) + grub_printf ("\n"); + + return 0; +} + + +GRUB_MOD_INIT(echo) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH, + "echo [-e|-n] FILE", "Display a line of text.", + options); +} + +GRUB_MOD_FINI(echo) +{ + grub_unregister_command ("echo"); +} diff --git a/commands/halt.c b/commands/halt.c new file mode 100644 index 0000000..c12c9d2 --- /dev/null +++ b/commands/halt.c @@ -0,0 +1,54 @@ +/* halt.c - command to halt the computer. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#if defined(GRUB_MACHINE_IEEE1275) +#include +#elif defined(GRUB_MACHINE_EFI) +#include +#else +/* Platforms shipping standalone halt, such as coreboot. */ +#include +#endif + +static grub_err_t +grub_cmd_halt (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_halt (); + return 0; +} + + +GRUB_MOD_INIT(halt) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH, + "halt", "halts the computer. This command does not" + " work on all firmware.", 0); +} + +GRUB_MOD_FINI(halt) +{ + grub_unregister_command ("halt"); +} diff --git a/commands/hdparm.c b/commands/hdparm.c new file mode 100644 index 0000000..9f2ba90 --- /dev/null +++ b/commands/hdparm.c @@ -0,0 +1,421 @@ +/* hdparm.c - command to get/set ATA disk parameters. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +static const struct grub_arg_option options[] = { + {"apm", 'B', 0, "set Advanced Power Management\n" + "(1=low, ..., 254=high, 255=off)", + 0, ARG_TYPE_INT}, + {"power", 'C', 0, "check power mode", 0, ARG_TYPE_NONE}, + {"security-freeze", 'F', 0, "freeze ATA security settings until reset", + 0, ARG_TYPE_NONE}, + {"health", 'H', 0, "check SMART health status", 0, ARG_TYPE_NONE}, + {"aam", 'M', 0, "set Automatic Acoustic Management\n" + "(0=off, 128=quiet, ..., 254=fast)", + 0, ARG_TYPE_INT}, + {"standby-timeout", 'S', 0, "set standby timeout\n" + "(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)", + 0, ARG_TYPE_INT}, + {"standby", 'y', 0, "set drive to standby mode", 0, ARG_TYPE_NONE}, + {"sleep", 'Y', 0, "set drive to sleep mode", 0, ARG_TYPE_NONE}, + {"identify", 'i', 0, "print drive identity and settings", + 0, ARG_TYPE_NONE}, + {"dumpid", 'I', 0, "dump contents of ATA IDENTIFY sector", + 0, ARG_TYPE_NONE}, + {"smart", -1, 0, "disable/enable SMART (0/1)", 0, ARG_TYPE_INT}, + {"quiet", 'q', 0, "do not print messages", 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} +}; + +enum grub_ata_smart_commands + { + GRUB_ATA_FEAT_SMART_ENABLE = 0xd8, + GRUB_ATA_FEAT_SMART_DISABLE = 0xd9, + GRUB_ATA_FEAT_SMART_STATUS = 0xda, + }; + +static int quiet = 0; + +static grub_err_t +grub_hdparm_do_ata_cmd (grub_disk_t disk, grub_uint8_t cmd, + grub_uint8_t features, grub_uint8_t sectors, + void * buffer, int size) +{ + struct grub_disk_ata_pass_through_parms apt; + grub_memset (&apt, 0, sizeof (apt)); + + apt.taskfile[GRUB_ATA_REG_CMD] = cmd; + apt.taskfile[GRUB_ATA_REG_FEATURES] = features; + apt.taskfile[GRUB_ATA_REG_SECTORS] = sectors; + apt.buffer = buffer; + apt.size = size; + + if (grub_disk_ata_pass_through (disk, &apt)) + return grub_errno; + + return GRUB_ERR_NONE; +} + +static int +grub_hdparm_do_check_powermode_cmd (grub_disk_t disk) +{ + struct grub_disk_ata_pass_through_parms apt; + grub_memset (&apt, 0, sizeof (apt)); + + apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_CHECK_POWER_MODE; + + if (grub_disk_ata_pass_through (disk, &apt)) + return -1; + + return apt.taskfile[GRUB_ATA_REG_SECTORS]; +} + +static int +grub_hdparm_do_smart_cmd (grub_disk_t disk, grub_uint8_t features) +{ + struct grub_disk_ata_pass_through_parms apt; + grub_memset (&apt, 0, sizeof (apt)); + + apt.taskfile[GRUB_ATA_REG_CMD] = GRUB_ATA_CMD_SMART; + apt.taskfile[GRUB_ATA_REG_FEATURES] = features; + apt.taskfile[GRUB_ATA_REG_LBAMID] = 0x4f; + apt.taskfile[GRUB_ATA_REG_LBAHIGH] = 0xc2; + + if (grub_disk_ata_pass_through (disk, &apt)) + return -1; + + if (features == GRUB_ATA_FEAT_SMART_STATUS) + { + if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0x4f + && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0xc2) + return 0; /* Good SMART status. */ + else if ( apt.taskfile[GRUB_ATA_REG_LBAMID] == 0xf4 + && apt.taskfile[GRUB_ATA_REG_LBAHIGH] == 0x2c) + return 1; /* Bad SMART status. */ + else + return -1; + } + return 0; +} + +static grub_err_t +grub_hdparm_simple_cmd (const char * msg, + grub_disk_t disk, grub_uint8_t cmd) +{ + if (! quiet && msg) + grub_printf ("%s", msg); + + grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, 0, 0, NULL, 0); + + if (! quiet && msg) + grub_printf ("%s\n", ! err ? "" : ": not supported"); + return err; +} + +static grub_err_t +grub_hdparm_set_val_cmd (const char * msg, int val, + grub_disk_t disk, grub_uint8_t cmd, + grub_uint8_t features, grub_uint8_t sectors) +{ + if (! quiet && msg && *msg) + { + if (val >= 0) + grub_printf ("Set %s to %d", msg, val); + else + grub_printf ("Disable %s", msg); + } + + grub_err_t err = grub_hdparm_do_ata_cmd (disk, cmd, features, sectors, + NULL, 0); + + if (! quiet && msg) + grub_printf ("%s\n", ! err ? "" : ": not supported"); + return err; +} + +static const char * +le16_to_char (char *dest, const grub_uint16_t * src16, unsigned bytes) +{ + grub_uint16_t * dest16 = (grub_uint16_t *) dest; + unsigned i; + for (i = 0; i < bytes / 2; i++) + dest16[i] = grub_be_to_cpu16 (src16[i]); + return dest; +} + +static void +grub_hdparm_print_identify (const char * idbuf) +{ + const grub_uint16_t * idw = (const grub_uint16_t *) idbuf; + + /* Print identity strings. */ + char tmp[40]; + grub_printf ("Model: \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40)); + grub_printf ("Firmware: \"%.8s\"\n", le16_to_char (tmp, &idw[23], 8)); + grub_printf ("Serial: \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20)); + + /* Print AAM, APM and SMART settings. */ + grub_uint16_t features1 = grub_le_to_cpu16 (idw[82]); + grub_uint16_t features2 = grub_le_to_cpu16 (idw[83]); + grub_uint16_t enabled1 = grub_le_to_cpu16 (idw[85]); + grub_uint16_t enabled2 = grub_le_to_cpu16 (idw[86]); + + grub_printf ("Automatic Acoustic Management: "); + if (features2 & 0x0200) + { + if (enabled2 & 0x0200) + { + grub_uint16_t aam = grub_le_to_cpu16 (idw[94]); + grub_printf ("%u (128=quiet, ..., 254=fast, recommended=%u)\n", + aam & 0xff, (aam >> 8) & 0xff); + } + else + grub_printf ("disabled\n"); + } + else + grub_printf ("not supported\n"); + + grub_printf ("Advanced Power Management: "); + if (features2 & 0x0008) + { + if (enabled2 & 0x0008) + grub_printf ("%u (1=low, ..., 254=high)\n", + grub_le_to_cpu16 (idw[91]) & 0xff); + else + grub_printf ("disabled\n"); + } + else + grub_printf ("not supported\n"); + + grub_printf ("SMART Feature Set: "); + if (features1 & 0x0001) + grub_printf ("%sabled\n", (enabled1 & 0x0001 ? "en" : "dis")); + else + grub_printf ("not supported\n"); + + /* Print security settings. */ + grub_uint16_t security = grub_le_to_cpu16 (idw[128]); + + grub_printf ("ATA Security: "); + if (security & 0x0001) + grub_printf ("%s, %s, %s, %s\n", + (security & 0x0002 ? "ENABLED" : "disabled"), + (security & 0x0004 ? "**LOCKED**" : "not locked"), + (security & 0x0008 ? "frozen" : "NOT FROZEN"), + (security & 0x0010 ? "COUNT EXPIRED" : "count not expired")); + else + grub_printf ("not supported\n"); +} + +static void +grub_hdparm_print_standby_tout (int timeout) +{ + if (timeout == 0) + grub_printf ("off"); + else if (timeout <= 252 || timeout == 255) + { + int h = 0, m = 0 , s = 0; + if (timeout == 255) + { + m = 21; + s = 15; + } + else if (timeout == 252) + m = 21; + else if (timeout <= 240) + { + s = timeout * 5; + m = s / 60; + s %= 60; + } + else + { + m = (timeout - 240) * 30; + h = m / 60; + m %= 60; + } + grub_printf ("%02d:%02d:%02d", h, m, s); + } + else + grub_printf ("invalid or vendor-specific"); +} + +static int get_int_arg (const struct grub_arg_list *state) +{ + return (state->set ? (int)grub_strtoul (state->arg, 0, 0) : -1); +} + + +static grub_err_t +grub_cmd_hdparm (struct grub_arg_list *state, int argc, char **args) // state???? +{ + /* Check command line. */ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing device name argument"); + + grub_size_t len = grub_strlen (args[0]); + if (! (args[0][0] == '(' && args[0][len - 1] == ')')) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "argument is not a device name"); + args[0][len - 1] = 0; + + if (! grub_disk_ata_pass_through) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "ATA pass through not available"); + + int i = 0; + int apm = get_int_arg (&state[i++]); + int power = state[i++].set; + int sec_freeze = state[i++].set; + int health = state[i++].set; + int aam = get_int_arg (&state[i++]); + int standby_tout = get_int_arg (&state[i++]); + int standby_now = state[i++].set; + int sleep_now = state[i++].set; + int ident = state[i++].set; + int dumpid = state[i++].set; + int enable_smart = get_int_arg (&state[i++]); + quiet = state[i++].set; + + /* Open disk. */ + grub_disk_t disk = grub_disk_open (&args[0][1]); + if (! disk) + return grub_errno; + + if (disk->partition) + { + grub_disk_close (disk); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "partition not allowed"); + } + + /* Change settings. */ + if (aam >= 0) + grub_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1), + disk, GRUB_ATA_CMD_SET_FEATURES, (aam ? 0x42 : 0xc2), aam); + + if (apm >= 0) + grub_hdparm_set_val_cmd ("Advanced Power Management", + (apm != 255 ? apm : -1), disk, GRUB_ATA_CMD_SET_FEATURES, + (apm != 255 ? 0x05 : 0x85), (apm != 255 ? apm : 0)); + + if (standby_tout >= 0) + { + if (! quiet) + { + grub_printf ("Set standby timeout to %d (", standby_tout); + grub_hdparm_print_standby_tout (standby_tout); + grub_printf (")"); + } + /* The IDLE cmd sets disk to idle mode and configures standby timer. */ + grub_hdparm_set_val_cmd ("", -1, disk, GRUB_ATA_CMD_IDLE, 0, standby_tout); + } + + if (enable_smart >= 0) + { + if (! quiet) + grub_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis")); + int err = grub_hdparm_do_smart_cmd (disk, (enable_smart ? + GRUB_ATA_FEAT_SMART_ENABLE : GRUB_ATA_FEAT_SMART_DISABLE)); + if (! quiet) + grub_printf ("%s\n", err ? ": not supported" : ""); + } + + if (sec_freeze) + grub_hdparm_simple_cmd ("Freeze security settings", disk, + GRUB_ATA_CMD_SECURITY_FREEZE_LOCK); + + /* Print/dump IDENTIFY. */ + if (ident || dumpid) + { + char buf[GRUB_DISK_SECTOR_SIZE]; + if (grub_hdparm_do_ata_cmd (disk, GRUB_ATA_CMD_IDENTIFY_DEVICE, + 0, 0, buf, sizeof (buf))) + grub_printf ("Cannot read ATA IDENTIFY data\n"); + else + { + if (ident) + grub_hdparm_print_identify (buf); + if (dumpid) + hexdump (0, buf, sizeof (buf)); + } + } + + /* Check power mode. */ + if (power) + { + grub_printf ("Disk power mode is: "); + int mode = grub_hdparm_do_check_powermode_cmd (disk); + if (mode < 0) + grub_printf ("unknown\n"); + else + grub_printf ("%s (0x%02x)\n", + (mode == 0xff ? "active/idle" : + mode == 0x80 ? "idle" : + mode == 0x00 ? "standby" : "unknown"), mode); + } + + /* Check health. */ + int status = 0; + if (health) + { + if (! quiet) + grub_printf ("SMART status is: "); + int err = grub_hdparm_do_smart_cmd (disk, GRUB_ATA_FEAT_SMART_STATUS); + if (! quiet) + grub_printf ("%s\n", (err < 0 ? "unknown" : + err == 0 ? "OK" : "*BAD*")); + status = (err > 0); + } + + /* Change power mode. */ + if (standby_now) + grub_hdparm_simple_cmd ("Set disk to standby mode", disk, + GRUB_ATA_CMD_STANDBY_IMMEDIATE); + + if (sleep_now) + grub_hdparm_simple_cmd ("Set disk to sleep mode", disk, + GRUB_ATA_CMD_SLEEP); + + grub_disk_close (disk); + + grub_errno = GRUB_ERR_NONE; + return status; +} + + +GRUB_MOD_INIT(hdparm) +{ + (void) mod; + + grub_register_command ("hdparm", grub_cmd_hdparm, GRUB_COMMAND_FLAG_BOTH, + "hdparm [OPTIONS] DISK", + "Get/set ATA disk parameters.", options); +} + +GRUB_MOD_FINI(hdparm) +{ + grub_unregister_command ("hdparm"); +} diff --git a/commands/help.c b/commands/help.c new file mode 100644 index 0000000..3e78cb9 --- /dev/null +++ b/commands/help.c @@ -0,0 +1,103 @@ +/* help.c - command to show a help text. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_help (struct grub_arg_list *state __attribute__ ((unused)), int argc, + char **args) + +{ + int cnt = 0; + char *currarg; + + auto int print_command_info (grub_command_t cmd); + auto int print_command_help (grub_command_t cmd); + + int print_command_info (grub_command_t cmd) + { + if (grub_command_find (cmd->name)) + { + if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) + { + char description[GRUB_TERM_WIDTH / 2]; + int desclen = grub_strlen (cmd->summary); + + /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled + with the description followed by spaces. */ + grub_memset (description, ' ', GRUB_TERM_WIDTH / 2 - 1); + description[GRUB_TERM_WIDTH / 2 - 1] = '\0'; + grub_memcpy (description, cmd->summary, + (desclen < GRUB_TERM_WIDTH / 2 - 1 + ? desclen : GRUB_TERM_WIDTH / 2 - 1)); + + grub_printf ("%s%s", description, (cnt++) % 2 ? "\n" : " "); + } + } + return 0; + } + + int print_command_help (grub_command_t cmd) + { + if (grub_command_find (cmd->name)) + { + if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) + { + if (cnt++ > 0) + grub_printf ("\n\n"); + + grub_arg_show_help (cmd); + } + } + return 0; + } + + if (argc == 0) + grub_iterate_commands (print_command_info); + else + { + int i; + + for (i = 0; i < argc; i++) + { + currarg = args[i]; + grub_iterate_commands (print_command_help); + } + } + + return 0; +} + + + +GRUB_MOD_INIT(help) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("help", grub_cmd_help, GRUB_COMMAND_FLAG_CMDLINE, + "help [PATTERN ...]", "Show a help message.", 0); +} + +GRUB_MOD_FINI(help) +{ + grub_unregister_command ("help"); +} diff --git a/commands/hexdump.c b/commands/hexdump.c new file mode 100644 index 0000000..10b6320 --- /dev/null +++ b/commands/hexdump.c @@ -0,0 +1,136 @@ +/* hexdump.c - command to dump the contents of a file or memory */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = { + {"skip", 's', 0, "skip offset bytes from the beginning of file.", 0, + ARG_TYPE_INT}, + {"length", 'n', 0, "read only length bytes", 0, ARG_TYPE_INT}, + {0, 0, 0, 0, 0, 0} +}; + +static grub_err_t +grub_cmd_hexdump (struct grub_arg_list *state, int argc, char **args) +{ + char buf[GRUB_DISK_SECTOR_SIZE * 4]; + grub_ssize_t size, length; + grub_addr_t skip; + int namelen; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + namelen = grub_strlen (args[0]); + skip = (state[0].set) ? grub_strtoul (state[0].arg, 0, 0) : 0; + length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256; + + if (!grub_strcmp (args[0], "(mem)")) + hexdump (skip, (char *) skip, length); + else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')')) + { + grub_disk_t disk; + grub_disk_addr_t sector; + grub_size_t ofs; + + args[0][namelen - 1] = 0; + disk = grub_disk_open (&args[0][1]); + if (! disk) + return 0; + + if (disk->partition) + skip += grub_partition_get_start (disk->partition) << GRUB_DISK_SECTOR_BITS; + + sector = (skip >> (GRUB_DISK_SECTOR_BITS + 2)) * 4; + ofs = skip & (GRUB_DISK_SECTOR_SIZE * 4 - 1); + while (length) + { + grub_size_t len, n; + + len = length; + if (ofs + len > sizeof (buf)) + len = sizeof (buf) - ofs; + + n = ((ofs + len + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + if (disk->dev->read (disk, sector, n, buf)) + break; + + hexdump (skip, &buf[ofs], len); + + ofs = 0; + skip += len; + length -= len; + sector += 4; + } + + grub_disk_close (disk); + } + else + { + grub_file_t file; + + file = grub_gzfile_open (args[0], 1); + if (! file) + return 0; + + file->offset = skip; + + while ((size = grub_file_read (file, buf, sizeof (buf))) > 0) + { + unsigned long len; + + len = ((length) && (size > length)) ? length : size; + hexdump (skip, buf, len); + skip += len; + if (length) + { + length -= len; + if (!length) + break; + } + } + + grub_file_close (file); + } + + return 0; +} + + +GRUB_MOD_INIT (hexdump) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("hexdump", grub_cmd_hexdump, GRUB_COMMAND_FLAG_BOTH, + "hexdump [OPTIONS] FILE_OR_DEVICE", + "Dump the contents of a file or memory.", options); +} + +GRUB_MOD_FINI (hexdump) +{ + grub_unregister_command ("hexdump"); +} diff --git a/commands/i386/cpuid.c b/commands/i386/cpuid.c new file mode 100644 index 0000000..87873d2 --- /dev/null +++ b/commands/i386/cpuid.c @@ -0,0 +1,93 @@ +/* cpuid.c - test for CPU features */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006, 2007 Free Software Foundation, Inc. + * Based on gcc/gcc/config/i386/driver-i386.c + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define cpuid(num,a,b,c,d) \ + asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (num)) + +#define bit_LM (1 << 29) + +static unsigned char has_longmode = 0; + +static const struct grub_arg_option options[] = + { + {"long-mode", 'l', 0, "check for long mode flag (default)", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_cpuid (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + return !has_longmode; +} + +GRUB_MOD_INIT(cpuid) +{ +#ifdef __x86_64__ + /* grub-emu */ + has_longmode = 1; +#else + unsigned int eax, ebx, ecx, edx; + unsigned int max_level; + unsigned int ext_level; + + /* See if we can use cpuid. */ + asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" + "pushl %0; popfl; pushfl; popl %0; popfl" + : "=&r" (eax), "=&r" (ebx) + : "i" (0x00200000)); + if (((eax ^ ebx) & 0x00200000) == 0) + goto done; + + /* Check the highest input value for eax. */ + cpuid (0, eax, ebx, ecx, edx); + /* We only look at the first four characters. */ + max_level = eax; + if (max_level == 0) + goto done; + + cpuid (0x80000000, eax, ebx, ecx, edx); + ext_level = eax; + if (ext_level < 0x80000000) + goto done; + + cpuid (0x80000001, eax, ebx, ecx, edx); + has_longmode = !!(edx & bit_LM); +done: +#endif + + grub_register_command ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_CMDLINE, + "cpuid", "Check for CPU features", options); +} + +GRUB_MOD_FINI(cpuid) +{ + grub_unregister_command ("cpuid"); +} diff --git a/commands/i386/pc/halt.c b/commands/i386/pc/halt.c new file mode 100644 index 0000000..c3660c5 --- /dev/null +++ b/commands/i386/pc/halt.c @@ -0,0 +1,57 @@ +/* halt.c - command to halt the computer. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"no-apm", 'n', 0, "do not use APM to halt the computer", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_halt (struct grub_arg_list *state, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) + +{ + int no_apm = 0; + if (state[0].set) + no_apm = 1; + grub_halt (no_apm); + return 0; +} + + + +GRUB_MOD_INIT(halt) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH, + "halt [-n]", + "Halt the system, if possible using APM", options); +} + +GRUB_MOD_FINI(halt) +{ + grub_unregister_command ("halt"); +} diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c new file mode 100644 index 0000000..4fbae08 --- /dev/null +++ b/commands/i386/pc/play.c @@ -0,0 +1,217 @@ +/* play.c - command to play a tune */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* Lots of this file is borrowed from GNU/Hurd generic-speaker driver. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BASE_TEMPO 120 + +/* The speaker port. */ +#define SPEAKER 0x61 + +/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output + from timer 2. */ +#define SPEAKER_TMR2 0x01 + +/* If SPEAKER_TMR2 is not set, this provides direct input into the + speaker. Otherwise, this enables or disables the output from the + timer. */ +#define SPEAKER_DATA 0x02 + +/* The PIT channel value ports. You can write to and read from them. + Do not mess with timer 0 or 1. */ +#define PIT_COUNTER_0 0x40 +#define PIT_COUNTER_1 0x41 +#define PIT_COUNTER_2 0x42 + +/* The frequency of the PIT clock. */ +#define PIT_FREQUENCY 0x1234dd + +/* The PIT control port. You can only write to it. Do not mess with + timer 0 or 1. */ +#define PIT_CTRL 0x43 +#define PIT_CTRL_SELECT_MASK 0xc0 +#define PIT_CTRL_SELECT_0 0x00 +#define PIT_CTRL_SELECT_1 0x40 +#define PIT_CTRL_SELECT_2 0x80 + +/* Read and load control. */ +#define PIT_CTRL_READLOAD_MASK 0x30 +#define PIT_CTRL_COUNTER_LATCH 0x00 /* Hold timer value until read. */ +#define PIT_CTRL_READLOAD_LSB 0x10 /* Read/load the LSB. */ +#define PIT_CTRL_READLOAD_MSB 0x20 /* Read/load the MSB. */ +#define PIT_CTRL_READLOAD_WORD 0x30 /* Read/load the LSB then the MSB. */ + +/* Mode control. */ +#define PIT_CTRL_MODE_MASK 0x0e + +/* Interrupt on terminal count. Setting the mode sets output to low. + When counter is set and terminated, output is set to high. */ +#define PIT_CTRL_INTR_ON_TERM 0x00 + +/* Programmable one-shot. When loading counter, output is set to + high. When counter terminated, output is set to low. Can be + triggered again from that point on by setting the gate pin to + high. */ +#define PIT_CTRL_PROGR_ONE_SHOT 0x02 + +/* Rate generator. Output is low for one period of the counter, and + high for the other. */ +#define PIT_CTRL_RATE_GEN 0x04 + +/* Square wave generator. Output is low for one half of the period, + and high for the other half. */ +#define PIT_CTRL_SQUAREWAVE_GEN 0x06 + +/* Software triggered strobe. Setting the mode sets output to high. + When counter is set and terminated, output is set to low. */ +#define PIT_CTRL_SOFTSTROBE 0x08 + +/* Hardware triggered strobe. Like software triggered strobe, but + only starts the counter when the gate pin is set to high. */ +#define PIT_CTRL_HARDSTROBE 0x0a + +/* Count mode. */ +#define PIT_CTRL_COUNT_MASK 0x01 +#define PIT_CTRL_COUNT_BINARY 0x00 /* 16-bit binary counter. */ +#define PIT_CTRL_COUNT_BCD 0x01 /* 4-decade BCD counter. */ + +#define T_REST ((short) 0) +#define T_FINE ((short) -1) + +struct note +{ + short pitch; + short duration; +}; + +static void +beep_off (void) +{ + unsigned char status; + + status = grub_inb (SPEAKER); + grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER); +} + +static void +beep_on (short pitch) +{ + unsigned char status; + unsigned int counter; + + if (pitch < 20) + pitch = 20; + else if (pitch > 20000) + pitch = 20000; + + counter = PIT_FREQUENCY / pitch; + + /* Program timer 2. */ + grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD + | PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL); + grub_outb (counter & 0xff, PIT_COUNTER_2); /* LSB */ + grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2); /* MSB */ + + /* Start speaker. */ + status = grub_inb (SPEAKER); + grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER); +} + +static grub_err_t +grub_cmd_play (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_file_t file; + struct note buf; + int tempo; + unsigned int to; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + file = grub_file_open (args[0]); + if (! file) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + + if (grub_file_read (file, (void *) &tempo, sizeof(tempo)) != sizeof(tempo)) + { + grub_file_close (file); + return grub_error (GRUB_ERR_FILE_READ_ERROR, + "file doesn't even contains a full tempo record"); + } + + grub_dprintf ("play","tempo = %d\n", tempo); + + while (grub_file_read (file, (void *) &buf, + sizeof (struct note)) == sizeof (struct note) + && buf.pitch != T_FINE && grub_checkkey () < 0) + { + + grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch, + buf.duration); + + switch (buf.pitch) + { + case T_REST: + beep_off (); + break; + + default: + beep_on (buf.pitch); + break; + } + + to = grub_get_rtc () + BASE_TEMPO * buf.duration / tempo; + while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0)) + ; + + } + + beep_off (); + + grub_file_close (file); + + while (grub_checkkey () > 0) + grub_getkey (); + + return 0; +} + + +GRUB_MOD_INIT(play) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("play", grub_cmd_play, GRUB_COMMAND_FLAG_BOTH, + "play FILE", "Play a tune", 0); +} + +GRUB_MOD_FINI(play) +{ + grub_unregister_command ("play"); +} diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c new file mode 100644 index 0000000..2a2aadc --- /dev/null +++ b/commands/i386/pc/pxecmd.c @@ -0,0 +1,97 @@ +/* pxe.c - command to control the pxe driver */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = +{ + {"info", 'i', 0, "show PXE information.", 0, 0}, + {"bsize", 'b', 0, "set PXE block size", 0, ARG_TYPE_INT}, + {"unload", 'u', 0, "unload PXE stack.", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static void +print_ip (grub_uint32_t ip) +{ + int i; + + for (i = 0; i < 3; i++) + { + grub_printf ("%d.", ip & 0xFF); + ip >>= 8; + } + grub_printf ("%d", ip); +} + +static grub_err_t +grub_cmd_pxe (struct grub_arg_list *state, int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + if (! grub_pxe_pxenv) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment"); + + if (state[1].set) + { + int size; + + size = grub_strtoul (state[1].arg, 0, 0); + if (size < GRUB_PXE_MIN_BLKSIZE) + size = GRUB_PXE_MIN_BLKSIZE; + else if (size > GRUB_PXE_MAX_BLKSIZE) + size = GRUB_PXE_MAX_BLKSIZE; + + grub_pxe_blksize = size; + } + + if (state[0].set) + { + grub_printf ("blksize : %d\n", grub_pxe_blksize); + grub_printf ("client ip : "); + print_ip (grub_pxe_your_ip); + grub_printf ("\nserver ip : "); + print_ip (grub_pxe_server_ip); + grub_printf ("\ngateway ip : "); + print_ip (grub_pxe_gateway_ip); + grub_printf ("\n"); + } + + if (state[2].set) + grub_pxe_unload (); + + return 0; +} + +GRUB_MOD_INIT(pxecmd) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("pxe", grub_cmd_pxe, GRUB_COMMAND_FLAG_BOTH, + "pxe [-i|-b|-u]", + "Command to control the PXE device.", options); +} + +GRUB_MOD_FINI(pxecmd) +{ + grub_unregister_command ("pxe"); +} diff --git a/commands/i386/pc/vbeinfo.c b/commands/i386/pc/vbeinfo.c new file mode 100644 index 0000000..237ecdd --- /dev/null +++ b/commands/i386/pc/vbeinfo.c @@ -0,0 +1,187 @@ +/* vbeinfo.c - command to list compatible VBE video modes. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void * +real2pm (grub_vbe_farptr_t ptr) +{ + return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL) + + ((unsigned long) ptr & 0x0000FFFF)); +} + +static grub_err_t +grub_cmd_vbeinfo (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_vbe_info_block controller_info; + struct grub_vbe_mode_info_block mode_info_tmp; + grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE; + grub_uint16_t *video_mode_list; + grub_uint16_t *p; + grub_uint16_t *saved_video_mode_list; + grub_size_t video_mode_list_size; + grub_err_t err; + char *modevar; + + err = grub_vbe_probe (&controller_info); + if (err != GRUB_ERR_NONE) + return err; + + grub_printf ("VBE info: version: %d.%d OEM software rev: %d.%d\n", + controller_info.version >> 8, + controller_info.version & 0xFF, + controller_info.oem_software_rev >> 8, + controller_info.oem_software_rev & 0xFF); + + /* The total_memory field is in 64 KiB units. */ + grub_printf (" total memory: %d KiB\n", + (controller_info.total_memory << 16) / 1024); + + /* Because the information on video modes is stored in a temporary place, + it is better to copy it to somewhere safe. */ + p = video_mode_list = real2pm (controller_info.video_mode_ptr); + while (*p++ != 0xFFFF) + ; + + video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list; + saved_video_mode_list = grub_malloc (video_mode_list_size); + if (! saved_video_mode_list) + return grub_errno; + + grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size); + + grub_printf ("List of compatible video modes:\n"); + grub_printf ("Legend: P=Packed pixel, D=Direct color, " + "mask/pos=R/G/B/reserved\n"); + + /* Walk through all video modes listed. */ + for (p = saved_video_mode_list; *p != 0xFFFF; p++) + { + const char *memory_model = 0; + grub_uint32_t mode = (grub_uint32_t) *p; + + err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp); + if (err != GRUB_ERR_NONE) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_SUPPORTED) == 0) + /* If not available, skip it. */ + continue; + + if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_RESERVED_1) == 0) + /* Not enough information. */ + continue; + + if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0) + /* Monochrome is unusable. */ + continue; + + if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0) + /* We support only linear frame buffer modes. */ + continue; + + if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 0) + /* We allow only graphical modes. */ + continue; + + switch (mode_info_tmp.memory_model) + { + case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL: + memory_model = "Packed"; + break; + case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR: + memory_model = "Direct"; + break; + + default: + break; + } + + if (! memory_model) + continue; + + grub_printf ("0x%03x: %4d x %4d x %2d %s", + mode, + mode_info_tmp.x_resolution, + mode_info_tmp.y_resolution, + mode_info_tmp.bits_per_pixel, + memory_model); + + /* Show mask and position details for direct color modes. */ + if (mode_info_tmp.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR) + grub_printf (", mask: %d/%d/%d/%d pos: %d/%d/%d/%d", + mode_info_tmp.red_mask_size, + mode_info_tmp.green_mask_size, + mode_info_tmp.blue_mask_size, + mode_info_tmp.rsvd_mask_size, + mode_info_tmp.red_field_position, + mode_info_tmp.green_field_position, + mode_info_tmp.blue_field_position, + mode_info_tmp.rsvd_field_position); + grub_printf ("\n"); + } + + grub_free (saved_video_mode_list); + + /* Check existence of vbe_mode environment variable. */ + modevar = grub_env_get ("vbe_mode"); + + if (modevar != 0) + { + unsigned long value; + + value = grub_strtoul (modevar, 0, 0); + if (grub_errno == GRUB_ERR_NONE) + use_mode = value; + else + grub_errno = GRUB_ERR_NONE; + } + + grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode); + + return 0; +} + +GRUB_MOD_INIT(vbeinfo) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("vbeinfo", + grub_cmd_vbeinfo, + GRUB_COMMAND_FLAG_BOTH, + "vbeinfo", + "List compatible VESA BIOS extension video modes.", + 0); +} + +GRUB_MOD_FINI(vbeinfo) +{ + grub_unregister_command ("vbeinfo"); +} diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c new file mode 100644 index 0000000..570421d --- /dev/null +++ b/commands/i386/pc/vbetest.c @@ -0,0 +1,179 @@ +/* vbetest.c - command to test VESA BIOS Extension 2.0+ support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_vbetest (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_err_t err; + char *modevar; + struct grub_vbe_mode_info_block mode_info; + struct grub_vbe_info_block controller_info; + grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE; + grub_uint32_t old_mode; + grub_uint8_t *framebuffer = 0; + grub_uint32_t bytes_per_scan_line = 0; + unsigned char *ptr; + int i; + + grub_printf ("Probing for VESA BIOS Extension ... "); + + /* Check if VESA BIOS exists. */ + err = grub_vbe_probe (&controller_info); + if (err != GRUB_ERR_NONE) + return err; + + grub_printf ("found!\n"); + + /* Dump out controller information. */ + grub_printf ("VBE signature = %c%c%c%c\n", + controller_info.signature[0], + controller_info.signature[1], + controller_info.signature[2], + controller_info.signature[3]); + + grub_printf ("VBE version = %d.%d\n", + controller_info.version >> 8, + controller_info.version & 0xFF); + grub_printf ("OEM string ptr = %08x\n", + controller_info.oem_string_ptr); + grub_printf ("Total memory = %d\n", + controller_info.total_memory); + + err = grub_vbe_get_video_mode (&old_mode); + grub_printf ("Get video mode err = %04x\n", err); + + if (err == GRUB_ERR_NONE) + grub_printf ("Old video mode = %04x\n", old_mode); + else + grub_errno = GRUB_ERR_NONE; + + /* Check existence of vbe_mode environment variable. */ + modevar = grub_env_get ("vbe_mode"); + if (modevar != 0) + { + unsigned long value; + + value = grub_strtoul (modevar, 0, 0); + if (grub_errno == GRUB_ERR_NONE) + use_mode = value; + else + grub_errno = GRUB_ERR_NONE; + } + + err = grub_vbe_get_video_mode_info (use_mode, &mode_info); + if (err != GRUB_ERR_NONE) + return err; + + /* Dump out details about the mode being tested. */ + grub_printf ("mode: 0x%03x\n", + use_mode); + grub_printf ("width : %d\n", + mode_info.x_resolution); + grub_printf ("height: %d\n", + mode_info.y_resolution); + grub_printf ("memory model: %02x\n", + mode_info.memory_model); + grub_printf ("bytes/scanline: %d\n", + mode_info.bytes_per_scan_line); + grub_printf ("bytes/scanline (lin): %d\n", + mode_info.lin_bytes_per_scan_line); + grub_printf ("base address: %08x\n", + mode_info.phys_base_addr); + grub_printf ("red mask/pos: %d/%d\n", + mode_info.red_mask_size, + mode_info.red_field_position); + grub_printf ("green mask/pos: %d/%d\n", + mode_info.green_mask_size, + mode_info.green_field_position); + grub_printf ("blue mask/pos: %d/%d\n", + mode_info.blue_mask_size, + mode_info.blue_field_position); + + grub_printf ("Press any key to continue.\n"); + + grub_getkey (); + + /* Setup GFX mode. */ + err = grub_vbe_set_video_mode (use_mode, &mode_info); + if (err != GRUB_ERR_NONE) + return err; + + /* Determine framebuffer address and how many bytes are in scan line. */ + framebuffer = (grub_uint8_t *) mode_info.phys_base_addr; + ptr = framebuffer; + + if (controller_info.version >= 0x300) + { + bytes_per_scan_line = mode_info.lin_bytes_per_scan_line; + } + else + { + bytes_per_scan_line = mode_info.bytes_per_scan_line; + } + + /* Draw some random data to screen. */ + for (i = 0; i < 256 * 256; i++) + { + ptr[i] = i & 0x0F; + } + + /* Draw white line to screen. */ + for (i = 0; i < 100; i++) + { + ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F; + } + + /* Draw another white line to screen. */ + grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line); + + grub_getkey (); + + /* Restore old video mode. */ + grub_vbe_set_video_mode (old_mode, 0); + + return grub_errno; +} + +GRUB_MOD_INIT(vbetest) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("vbetest", + grub_cmd_vbetest, + GRUB_COMMAND_FLAG_BOTH, + "vbetest", + "Test VESA BIOS Extension 2.0+ support", + 0); +} + +GRUB_MOD_FINI(vbetest) +{ + grub_unregister_command ("vbetest"); +} diff --git a/commands/ieee1275/suspend.c b/commands/ieee1275/suspend.c new file mode 100644 index 0000000..e6b9feb --- /dev/null +++ b/commands/ieee1275/suspend.c @@ -0,0 +1,48 @@ +/* suspend.c - command to suspend GRUB and return to Open Firmware */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_suspend (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_printf ("Run 'go' to resume GRUB.\n"); + grub_ieee1275_enter (); + grub_cls (); + return 0; +} + + +GRUB_MOD_INIT(ieee1275_suspend) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("suspend", grub_cmd_suspend, GRUB_COMMAND_FLAG_BOTH, + "suspend", "Return to Open Firmware prompt", 0); +} + +GRUB_MOD_FINI(ieee1275_suspend) +{ + grub_unregister_command ("suspend"); +} diff --git a/commands/loadenv.c b/commands/loadenv.c new file mode 100644 index 0000000..4dbf1d9 --- /dev/null +++ b/commands/loadenv.c @@ -0,0 +1,257 @@ +/* loadenv.c - command to load/save environment variable. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"file", 'f', 0, "specify filename", 0, ARG_TYPE_PATHNAME}, + {0, 0, 0, 0, 0, 0} + }; + +char buffer[GRUB_ENVBLK_MAXLEN]; +grub_envblk_t envblk; + +static grub_file_t +read_envblk_file (char *filename, void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length)) +{ + char *buf = 0; + grub_file_t file; + + if (! filename) + { + char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + int len; + + len = grub_strlen (prefix); + buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); + grub_strcpy (buf, prefix); + buf[len] = '/'; + grub_strcpy (buf + len + 1, GRUB_ENVBLK_DEFCFG); + filename = buf; + } + else + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "prefix is not found"); + return 0; + } + } + + file = grub_file_open (filename); + grub_free (buf); + if (! file) + return 0; + + if (read_hook) + { + if (! file->device->disk) + { + grub_file_close (file); + grub_error (GRUB_ERR_BAD_DEVICE, + "this command is available only for disk devices."); + return 0; + } + file->read_hook = read_hook; + } + + if (grub_file_read (file, buffer, GRUB_ENVBLK_MAXLEN) != GRUB_ENVBLK_MAXLEN) + { + grub_file_close (file); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "file too short"); + return 0; + } + + envblk = grub_envblk_find (buffer); + if (! envblk) + { + grub_file_close (file); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "environment block not found"); + return 0; + } + + return file; +} + +static grub_err_t +grub_cmd_load_env (struct grub_arg_list *state, + int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) + +{ + grub_file_t file; + + auto int hook (char *name, char *value); + int hook (char *name, char *value) + { + grub_env_set (name, value); + + return 0; + } + + file = read_envblk_file ((state[0].set) ? state[0].arg : 0, 0); + if (! file) + return grub_errno; + + grub_file_close (file); + + grub_envblk_iterate (envblk, hook); + + return grub_errno; +} + +static grub_err_t +grub_cmd_list_env (struct grub_arg_list *state, + int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) +{ + grub_file_t file; + + auto int hook (char *name, char *value); + int hook (char *name, char *value) + { + grub_printf ("%s=%s\n", name, value); + + return 0; + } + + file = read_envblk_file ((state[0].set) ? state[0].arg : 0, 0); + if (! file) + return grub_errno; + + grub_file_close (file); + + grub_envblk_iterate (envblk, hook); + + return grub_errno; +} + +static grub_err_t +grub_cmd_save_env (struct grub_arg_list *state, int argc, char **args) +{ + grub_file_t file; + grub_disk_t disk; + grub_disk_addr_t addr[GRUB_ENVBLK_MAXLEN >> GRUB_DISK_SECTOR_BITS]; + char buf[GRUB_DISK_SECTOR_SIZE]; + grub_disk_addr_t part_start = 0; + int num = 0; + + auto void NESTED_FUNC_ATTR hook (grub_disk_addr_t sector, unsigned offset, + unsigned length); + + void NESTED_FUNC_ATTR hook (grub_disk_addr_t sector, + unsigned offset, unsigned length) + { + if ((offset != 0) || (length != GRUB_DISK_SECTOR_SIZE)) + return; + + if (num < (GRUB_ENVBLK_MAXLEN >> GRUB_DISK_SECTOR_BITS)) + addr[num++] = sector; + } + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "No variable is specified"); + + file = read_envblk_file ((state[0].set) ? state[0].arg : 0, hook); + if (! file) + return grub_errno; + + file->read_hook = 0; + + if (num != GRUB_ENVBLK_MAXLEN >> GRUB_DISK_SECTOR_BITS) + { + grub_error (GRUB_ERR_BAD_DEVICE, "invalid blocklist"); + goto quit; + } + + disk = file->device->disk; + if (disk->partition) + part_start = grub_partition_get_start (disk->partition); + + for (num = 0; num < (GRUB_ENVBLK_MAXLEN >> GRUB_DISK_SECTOR_BITS); num++) + { + if (grub_disk_read (disk, addr[num] - part_start, 0, + GRUB_DISK_SECTOR_SIZE, buf)) + goto quit; + + if (grub_memcmp (&buffer[num << GRUB_DISK_SECTOR_BITS], buf, + GRUB_DISK_SECTOR_SIZE)) + { + grub_error (GRUB_ERR_BAD_DEVICE, "invalid blocklist"); + goto quit; + } + } + + while (argc) + { + char *value; + + value = grub_env_get (args[0]); + if (value) + { + if (grub_envblk_insert (envblk, args[0], value)) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small"); + goto quit; + } + } + + argc--; + args++; + } + + for (num = 0; num < (GRUB_ENVBLK_MAXLEN >> GRUB_DISK_SECTOR_BITS); num++) + if (grub_disk_write (disk, addr[num] - part_start, 0, + GRUB_DISK_SECTOR_SIZE, + &buffer[num << GRUB_DISK_SECTOR_BITS])) + goto quit; + +quit: + grub_file_close (file); + + return grub_errno; +} + +GRUB_MOD_INIT(loadenv) +{ + (void) mod; + grub_register_command ("load_env", grub_cmd_load_env, GRUB_COMMAND_FLAG_BOTH, + "load_env [-f FILE]", "Load variables from environment block file.", options); + grub_register_command ("list_env", grub_cmd_list_env, GRUB_COMMAND_FLAG_BOTH, + "list_env [-f FILE]", "List variables from environment block file.", options); + grub_register_command ("save_env", grub_cmd_save_env, GRUB_COMMAND_FLAG_BOTH, + "save_env [-f FILE] variable_name [...]", "Save variables to environment block file.", options); +} + +GRUB_MOD_FINI(loadenv) +{ + grub_unregister_command ("load_env"); + grub_unregister_command ("list_env"); + grub_unregister_command ("save_env"); +} diff --git a/commands/ls.c b/commands/ls.c new file mode 100644 index 0000000..7f5a609 --- /dev/null +++ b/commands/ls.c @@ -0,0 +1,245 @@ +/* ls.c - command to list files and devices */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"long", 'l', 0, "show a long list with more detailed information", 0, 0}, + {"human-readable", 'h', 0, "print sizes in a human readable format", 0, 0}, + {"all", 'a', 0, "list all files", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'}; + +static grub_err_t +grub_ls_list_devices (int longlist) +{ + auto int grub_ls_print_devices (const char *name); + int grub_ls_print_devices (const char *name) + { + if (longlist) + grub_normal_print_device_info (name); + else + grub_printf ("(%s) ", name); + + return 0; + } + + grub_device_iterate (grub_ls_print_devices); + grub_putchar ('\n'); + grub_refresh (); + + return 0; +} + +static grub_err_t +grub_ls_list_files (char *dirname, int longlist, int all, int human) +{ + char *device_name; + grub_fs_t fs; + const char *path; + grub_device_t dev; + auto int print_files (const char *filename, int dir); + auto int print_files_long (const char *filename, int dir); + + int print_files (const char *filename, int dir) + { + if (all || filename[0] != '.') + grub_printf ("%s%s ", filename, dir ? "/" : ""); + + return 0; + } + + int print_files_long (const char *filename, int dir) + { + char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1]; + + if ((! all) && (filename[0] == '.')) + return 0; + + if (! dir) + { + grub_file_t file; + + if (dirname[grub_strlen (dirname) - 1] == '/') + grub_sprintf (pathname, "%s%s", dirname, filename); + else + grub_sprintf (pathname, "%s/%s", dirname, filename); + + /* XXX: For ext2fs symlinks are detected as files while they + should be reported as directories. */ + file = grub_file_open (pathname); + if (! file) + { + grub_errno = 0; + return 0; + } + + if (! human) + grub_printf ("%-12llu", (unsigned long long) file->size); + else + { + grub_uint64_t fsize = file->size * 100ULL; + int fsz = file->size; + int units = 0; + char buf[20]; + + while (fsz / 1024) + { + fsize = (fsize + 512) / 1024; + fsz /= 1024; + units++; + } + + if (units) + { + grub_uint32_t whole, fraction; + + whole = grub_divmod64 (fsize, 100, &fraction); + grub_sprintf (buf, "%u.%02u%c", whole, fraction, + grub_human_sizes[units]); + grub_printf ("%-12s", buf); + } + else + grub_printf ("%-12llu", (unsigned long long) file->size); + + } + grub_file_close (file); + } + else + grub_printf ("%-12s", "DIR"); + + grub_printf ("%s%s\n", filename, dir ? "/" : ""); + + return 0; + } + + device_name = grub_file_get_device_name (dirname); + dev = grub_device_open (device_name); + if (! dev) + goto fail; + + fs = grub_fs_probe (dev); + path = grub_strchr (dirname, ')'); + if (! path) + path = dirname; + else + path++; + + if (! path && ! device_name) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); + goto fail; + } + + if (! *path) + { + if (grub_errno == GRUB_ERR_UNKNOWN_FS) + grub_errno = GRUB_ERR_NONE; + + grub_normal_print_device_info (device_name); + } + else if (fs) + { + if (longlist) + (fs->dir) (dev, path, print_files_long); + else + (fs->dir) (dev, path, print_files); + + if (grub_errno == GRUB_ERR_BAD_FILE_TYPE + && path[grub_strlen (path) - 1] != '/') + { + /* PATH might be a regular file. */ + char *p; + grub_file_t file; + + grub_errno = 0; + + file = grub_file_open (dirname); + if (! file) + goto fail; + + grub_file_close (file); + + p = grub_strrchr (dirname, '/') + 1; + dirname = grub_strndup (dirname, p - dirname); + if (! dirname) + goto fail; + + all = 1; + if (longlist) + print_files_long (p, 0); + else + print_files (p, 0); + + grub_free (dirname); + } + + if (grub_errno == GRUB_ERR_NONE) + grub_putchar ('\n'); + + grub_refresh (); + } + + fail: + if (dev) + grub_device_close (dev); + + grub_free (device_name); + + return 0; +} + +static grub_err_t +grub_cmd_ls (struct grub_arg_list *state, int argc, char **args) +{ + if (argc == 0) + grub_ls_list_devices (state[0].set); + else + grub_ls_list_files (args[0], state[0].set, state[2].set, + state[1].set); + + return 0; +} + +GRUB_MOD_INIT(ls) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH, + "ls [-l|-h|-a] [FILE]", + "List devices and files.", options); +} + +GRUB_MOD_FINI(ls) +{ + grub_unregister_command ("ls"); +} diff --git a/commands/lsmmap.c b/commands/lsmmap.c new file mode 100644 index 0000000..c705591 --- /dev/null +++ b/commands/lsmmap.c @@ -0,0 +1,53 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_lsmmap (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) + +{ + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n", + addr, size, type); + return 0; + } + grub_machine_mmap_iterate (hook); + + return 0; +} + + +GRUB_MOD_INIT(lsmmap) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("lsmmap", grub_cmd_lsmmap, GRUB_COMMAND_FLAG_BOTH, + "lsmmap", "List memory map provided by firmware.", 0); +} + +GRUB_MOD_FINI(lsmmap) +{ + grub_unregister_command ("lsmmap"); +} diff --git a/commands/lspci.c b/commands/lspci.c new file mode 100644 index 0000000..9791800 --- /dev/null +++ b/commands/lspci.c @@ -0,0 +1,171 @@ +/* lspci.c - List PCI devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct grub_pci_classname +{ + int class; + int subclass; + char *desc; +}; + +static const struct grub_pci_classname grub_pci_classes[] = + { + { 0, 0, "" }, + { 1, 0, "SCSI Controller" }, + { 1, 1, "IDE Controller" }, + { 1, 2, "Floppy Controller" }, + { 1, 3, "IPI Controller" }, + { 1, 4, "RAID Controller" }, + { 1, 6, "SATA Controller" }, + { 1, 0x80, "Mass storage Controller" }, + { 2, 0, "Ethernet Controller" }, + { 2, 1, "Token Ring Controller" }, + { 2, 2, "FDDI Controller" }, + { 2, 3, "ATM Controller" }, + { 2, 4, "ISDN Controller" }, + { 2, 0x80, "Network controller" }, + { 3, 0, "VGA Controller" }, + { 3, 1, "XGA Controller" }, + { 3, 2, "3D Controller" }, + { 3, 0x80, "Display Controller" }, + { 4, 0, "Multimedia Video Device" }, + { 4, 1, "Multimedia Audio Device" }, + { 4, 2, "Multimedia Telephony Device" }, + { 4, 0x80, "Multimedia device" }, + { 5, 0, "RAM Controller" }, + { 5, 1, "Flash Memory Controller" }, + { 5, 0x80, "Memory Controller" }, + { 6, 0, "Host Bridge" }, + { 6, 1, "ISA Bridge" }, + { 6, 2, "EISA Bride" }, + { 6, 3, "MCA Bridge" }, + { 6, 4, "PCI-PCI Bridge" }, + { 6, 5, "PCMCIA Bridge" }, + { 6, 6, "NuBus Bridge" }, + { 6, 7, "CardBus Bridge" }, + { 6, 8, "Raceway Bridge" }, + { 6, 0x80, "Unknown Bridge" }, + { 7, 0x80, "Communication controller" }, + { 8, 0x80, "System hardware" }, + { 9, 0, "Keyboard Controller" }, + { 9, 1, "Digitizer" }, + { 9, 2, "Mouse Controller" }, + { 9, 3, "Scanner Controller" }, + { 9, 4, "Gameport Controller" }, + { 9, 0x80, "Unknown Input Device" }, + { 10, 0, "Generic Docking Station" }, + { 10, 0x80, "Unknown Docking Station" }, + { 11, 0, "80386 Processor" }, + { 11, 1, "80486 Processor" }, + { 11, 2, "Pentium Processor" }, + { 11, 0x10, "Alpha Processor" }, + { 11, 0x20, "PowerPC Processor" }, + { 11, 0x30, "MIPS Processor" }, + { 11, 0x40, "Co-Processor" }, + { 11, 0x80, "Unknown Processor" }, + { 12, 0x80, "Serial Bus Controller" }, + { 13, 0x80, "Wireless Controller" }, + { 14, 0, "I2O" }, + { 15, 0, "IrDA Controller" }, + { 15, 1, "Consumer IR" }, + { 15, 0x10, "RF-Controller" }, + { 15, 0x80, "Satellite Communication Controller" }, + { 16, 0, "Network Decryption" }, + { 16, 1, "Entertainment Decryption" }, + { 16, 0x80, "Unknown Decryption Controller" }, + { 17, 0, "Digital IO Module" }, + { 17, 0x80, "Unknown Data Input System" }, + { 0, 0, 0 }, + }; + +static const char * +grub_pci_get_class (int class, int subclass) +{ + const struct grub_pci_classname *curr = grub_pci_classes; + + while (curr->desc) + { + if (curr->class == class && curr->subclass == subclass) + return curr->desc; + curr++; + } + + return 0; +} + +static int +grub_lspci_iter (int bus, int dev, int func, grub_pci_id_t pciid) +{ + grub_uint32_t class; + const char *sclass; + grub_pci_address_t addr; + + grub_printf ("%02x:%02x.%x %04x:%04x", bus, dev, func, pciid & 0xFFFF, + pciid >> 16); + addr = grub_pci_make_address (bus, dev, func, 2); + class = grub_pci_read (addr); + + /* Lookup the class name, if there isn't a specific one, + retry with 0x80 to get the generic class name. */ + sclass = grub_pci_get_class (class >> 24, (class >> 16) & 0xFF); + if (! sclass) + sclass = grub_pci_get_class (class >> 24, 0x80); + if (! sclass) + sclass = ""; + + grub_printf (" [%04x] %s", (class >> 16) & 0xffff, sclass); + + grub_uint8_t pi = (class >> 8) & 0xff; + if (pi) + grub_printf (" [PI %02x]", pi); + + grub_printf ("\n"); + + return 0; +} + +static grub_err_t +grub_cmd_lspci (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_pci_iterate (grub_lspci_iter); + return GRUB_ERR_NONE; +} + + + + +GRUB_MOD_INIT(pci) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH, + "lspci", "List PCI devices", 0); +} + + +GRUB_MOD_FINI(pci) +{ + grub_unregister_command ("lspci"); +} diff --git a/commands/read.c b/commands/read.c new file mode 100644 index 0000000..4aa4f76 --- /dev/null +++ b/commands/read.c @@ -0,0 +1,86 @@ +/* read.c - Command to read variables from user. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static char * +grub_getline (void) +{ + int i; + char *line; + char *tmp; + char c; + + i = 0; + line = grub_malloc (1 + i + sizeof('\0')); + if (! line) + return NULL; + + while (1) + { + c = grub_getkey (); + if ((c == '\n') || (c == '\r')) + break; + + line[i] = c; + if (grub_isprint (c)) + grub_putchar (c); + i++; + tmp = grub_realloc (line, 1 + i + sizeof('\0')); + if (! tmp) + { + grub_free (line); + return NULL; + } + line = tmp; + } + line[i] = '\0'; + + return line; +} + +static grub_err_t +grub_cmd_read (struct grub_arg_list *state UNUSED, int argc, char **args) +{ + char *line = grub_getline (); + if (! line) + return grub_errno; + if (argc > 0) + grub_env_set (args[0], line); + + grub_free (line); + return 0; +} + + +GRUB_MOD_INIT(read) +{ + grub_register_command ("read", grub_cmd_read, GRUB_COMMAND_FLAG_CMDLINE, + "read [ENVVAR]", "Set variable with user input", 0); +} + +GRUB_MOD_FINI(read) +{ + grub_unregister_command ("read"); +} diff --git a/commands/reboot.c b/commands/reboot.c new file mode 100644 index 0000000..bff7a57 --- /dev/null +++ b/commands/reboot.c @@ -0,0 +1,56 @@ +/* reboot.c - command to reboot the computer. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#if defined(GRUB_MACHINE_IEEE1275) +#include +#elif defined(GRUB_MACHINE_EFI) +#include +#elif defined(GRUB_MACHINE_PCBIOS) +#include +#else +/* Platforms shipping standalone reboot, such as coreboot. */ +#include +#endif + + +static grub_err_t +grub_cmd_reboot (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_reboot (); + return 0; +} + + +GRUB_MOD_INIT(reboot) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("reboot", grub_cmd_reboot, GRUB_COMMAND_FLAG_BOTH, + "reboot", "Reboot the computer", 0); +} + +GRUB_MOD_FINI(reboot) +{ + grub_unregister_command ("reboot"); +} diff --git a/commands/search.c b/commands/search.c new file mode 100644 index 0000000..a07259a --- /dev/null +++ b/commands/search.c @@ -0,0 +1,234 @@ +/* search.c - search devices based on a file or a filesystem label */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"file", 'f', 0, "search devices by a file (default)", 0, 0}, + {"label", 'l', 0, "search devices by a filesystem label", 0, 0}, + {"fs-uuid", 'u', 0, "search devices by a filesystem UUID", 0, 0}, + {"set", 's', GRUB_ARG_OPTION_OPTIONAL, "set a variable to the first device found", "VAR", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +static void +search_label (const char *key, const char *var) +{ + int count = 0; + auto int iterate_device (const char *name); + + int iterate_device (const char *name) + { + grub_device_t dev; + int abort = 0; + + dev = grub_device_open (name); + if (dev) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + if (fs && fs->label) + { + char *label; + + (fs->label) (dev, &label); + if (grub_errno == GRUB_ERR_NONE && label) + { + if (grub_strcmp (label, key) == 0) + { + /* Found! */ + count++; + if (var) + { + grub_env_set (var, name); + abort = 1; + } + else + grub_printf (" %s", name); + } + + grub_free (label); + } + } + + grub_device_close (dev); + } + + grub_errno = GRUB_ERR_NONE; + return abort; + } + + grub_device_iterate (iterate_device); + + if (count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); +} + +static void +search_fs_uuid (const char *key, const char *var) +{ + int count = 0; + auto int iterate_device (const char *name); + + int iterate_device (const char *name) + { + grub_device_t dev; + int abort = 0; + + dev = grub_device_open (name); + if (dev) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + if (fs && fs->uuid) + { + char *uuid; + + (fs->uuid) (dev, &uuid); + if (grub_errno == GRUB_ERR_NONE && uuid) + { + if (grub_strcasecmp (uuid, key) == 0) + { + /* Found! */ + count++; + if (var) + { + grub_env_set (var, name); + abort = 1; + } + else + grub_printf (" %s", name); + } + + grub_free (uuid); + } + } + + grub_device_close (dev); + } + + grub_errno = GRUB_ERR_NONE; + return abort; + } + + grub_device_iterate (iterate_device); + + if (count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); +} + +static void +search_file (const char *key, const char *var) +{ + int count = 0; + char *buf = 0; + auto int iterate_device (const char *name); + + int iterate_device (const char *name) + { + grub_size_t len; + char *p; + grub_file_t file; + int abort = 0; + + len = grub_strlen (name) + 2 + grub_strlen (key) + 1; + p = grub_realloc (buf, len); + if (! p) + return 1; + + buf = p; + grub_sprintf (buf, "(%s)%s", name, key); + + file = grub_file_open (buf); + if (file) + { + /* Found! */ + count++; + if (var) + { + grub_env_set (var, name); + abort = 1; + } + else + grub_printf (" %s", name); + + grub_file_close (file); + } + + grub_errno = GRUB_ERR_NONE; + return abort; + } + + grub_device_iterate (iterate_device); + + grub_free (buf); + + if (grub_errno == GRUB_ERR_NONE && count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device"); +} + +static grub_err_t +grub_cmd_search (struct grub_arg_list *state, int argc, char **args) +{ + const char *var = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_INVALID_COMMAND, "no argument specified"); + + if (state[3].set) + var = state[3].arg ? state[3].arg : "root"; + + if (state[1].set) + search_label (args[0], var); + else if (state[2].set) + search_fs_uuid (args[0], var); + else + search_file (args[0], var); + + return grub_errno; +} + +GRUB_MOD_INIT(search) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH, + "search [-f|-l|-u|-s] NAME", + "Search devices by file, filesystem label or filesystem UUID." + " If --set is specified, the first device found is" + " set to a variable. If no variable name is" + " specified, \"root\" is used.", + options); +} + +GRUB_MOD_FINI(search) +{ + grub_unregister_command ("search"); +} diff --git a/commands/sleep.c b/commands/sleep.c new file mode 100644 index 0000000..46c1326 --- /dev/null +++ b/commands/sleep.c @@ -0,0 +1,112 @@ +/* sleep.c - Command to wait a specified number of seconds. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"verbose", 'v', 0, "verbose countdown", 0, 0}, + {"interruptible", 'i', 0, "interruptible with ESC", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_uint8_t x, y; + +static void +do_print (int n) +{ + grub_gotoxy (x, y); + /* NOTE: Do not remove the trailing space characters. + They are required to clear the line. */ + grub_printf ("%d ", n); +} + +/* Based on grub_millisleep() from kern/generic/millisleep.c. */ +static int +grub_interruptible_millisleep (grub_uint32_t ms) +{ + grub_uint64_t start; + + start = grub_get_time_ms (); + + while (grub_get_time_ms () - start < ms) + if (grub_checkkey () >= 0 && + GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC) + return 1; + + return 0; +} + +static grub_err_t +grub_cmd_sleep (struct grub_arg_list *state, int argc, char **args) +{ + grub_uint16_t xy; + int n; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing operand"); + + n = grub_strtoul (args[0], 0, 10); + + if (n == 0) + { + /* Either `0' or broken input. */ + return 0; + } + + xy = grub_getxy (); + x = xy >> 8; + y = xy & 0xff; + + for (; n; n--) + { + if (state[0].set) + do_print (n); + + if (state[1].set) + { + if (grub_interruptible_millisleep (1000)) + return 1; + } + else + grub_millisleep (1000); + } + if (state[0].set) + do_print (0); + + return 0; +} + + +GRUB_MOD_INIT(sleep) +{ + grub_register_command ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH, + "sleep NUMBER_OF_SECONDS", "Wait for a specified number of seconds", options); +} + +GRUB_MOD_FINI(sleep) +{ + grub_unregister_command ("sleep"); +} diff --git a/commands/terminal.c b/commands/terminal.c new file mode 100644 index 0000000..98e6d11 --- /dev/null +++ b/commands/terminal.c @@ -0,0 +1,132 @@ +/* terminal.c - command to show and select a terminal */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_terminal_input (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_term_input_t term = 0; + + auto int print_terminal (grub_term_input_t); + auto int find_terminal (grub_term_input_t); + + int print_terminal (grub_term_input_t t) + { + grub_printf (" %s", t->name); + return 0; + } + + int find_terminal (grub_term_input_t t) + { + if (grub_strcmp (t->name, args[0]) == 0) + { + term = t; + return 1; + } + + return 0; + } + + if (argc == 0) + { + grub_printf ("Available input terminal(s):"); + grub_term_iterate_input (print_terminal); + grub_putchar ('\n'); + + grub_printf ("Current input terminal: %s\n", grub_term_get_current_input ()->name); + } + else + { + grub_term_iterate_input (find_terminal); + if (! term) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such input terminal"); + + grub_term_set_current_input (term); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_terminal_output (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_term_output_t term = 0; + + auto int print_terminal (grub_term_output_t); + auto int find_terminal (grub_term_output_t); + + int print_terminal (grub_term_output_t t) + { + grub_printf (" %s", t->name); + return 0; + } + + int find_terminal (grub_term_output_t t) + { + if (grub_strcmp (t->name, args[0]) == 0) + { + term = t; + return 1; + } + + return 0; + } + + if (argc == 0) + { + grub_printf ("Available output terminal(s):"); + grub_term_iterate_output (print_terminal); + grub_putchar ('\n'); + + grub_printf ("Current output terminal: %s\n", grub_term_get_current_output ()->name); + } + else + { + grub_term_iterate_output (find_terminal); + if (! term) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such output terminal"); + + grub_term_set_current_output (term); + } + + return GRUB_ERR_NONE; +} + + +GRUB_MOD_INIT(terminal) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("terminal_input", grub_cmd_terminal_input, GRUB_COMMAND_FLAG_BOTH, + "terminal_input [TERM...]", "Select an input terminal.", 0); + grub_register_command ("terminal_output", grub_cmd_terminal_output, GRUB_COMMAND_FLAG_BOTH, + "terminal_output [TERM...]", "Select an output terminal.", 0); +} + +GRUB_MOD_FINI(terminal) +{ + grub_unregister_command ("terminal_input"); + grub_unregister_command ("terminal_output"); +} diff --git a/commands/test.c b/commands/test.c new file mode 100644 index 0000000..3d273db --- /dev/null +++ b/commands/test.c @@ -0,0 +1,70 @@ +/* test.c -- The test command.. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_test (struct grub_arg_list *state __attribute__ ((unused)), int argc, + char **args) + +{ + char *eq; + char *eqis; + + /* XXX: No fancy expression evaluation yet. */ + + if (argc == 0) + return 0; + + eq = grub_strdup (args[0]); + eqis = grub_strchr (eq, '='); + if (! eqis) + return 0; + + *eqis = '\0'; + eqis++; + /* Check an expression in the form `A=B'. */ + if (grub_strcmp (eq, eqis)) + grub_error (GRUB_ERR_TEST_FAILURE, "false"); + grub_free (eq); + + return grub_errno; +} + + + +GRUB_MOD_INIT(test) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("[", grub_cmd_test, GRUB_COMMAND_FLAG_CMDLINE, + "[ EXPRESSION ]", "Evaluate an expression", 0); + grub_register_command ("test", grub_cmd_test, GRUB_COMMAND_FLAG_CMDLINE, + "test EXPRESSION", "Evaluate an expression", 0); +} + +GRUB_MOD_FINI(test) +{ + grub_unregister_command ("["); + grub_unregister_command ("test"); +} diff --git a/commands/usbtest.c b/commands/usbtest.c new file mode 100644 index 0000000..8262b2e --- /dev/null +++ b/commands/usbtest.c @@ -0,0 +1,160 @@ +/* usbtest.c - test module for USB */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char *usb_classes[] = + { + "", + "Audio", + "Communication Interface", + "HID", + "", + "Physical", + "Image", + "Printer", + "Mass Storage", + "Hub", + "Data Interface", + "Smart Card", + "Content Security", + "Video" + }; + +static const char *usb_endp_type[] = + { + "Control", + "Isochronous", + "Bulk", + "Interrupt" + }; + +static const char *usb_devspeed[] = + { + "", + "Low", + "Full", + "High" + }; + +static void +usb_print_str (const char *description, grub_usb_device_t dev, int idx) +{ + char *name; + /* XXX: LANGID */ + + if (! idx) + return; + + grub_usb_get_string (dev, idx, 0x0409, &name); + grub_printf ("%s: `%s'\n", description, name); + grub_free (name); +} + +static int +usb_iterate (grub_usb_device_t dev) +{ + struct grub_usb_desc_device *descdev; + int i; + + descdev = &dev->descdev; + + usb_print_str ("Product", dev, descdev->strprod); + usb_print_str ("Vendor", dev, descdev->strvendor); + usb_print_str ("Serial", dev, descdev->strserial); + + if (descdev->class > 0 && descdev->class <= 0x0E) + grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", + descdev->class, usb_classes[descdev->class], + descdev->subclass, descdev->protocol); + grub_printf ("USB version %d.%d, VendorID: 0x%02x, ProductID: 0x%02x, #conf: %d\n", + descdev->usbrel >> 8, (descdev->usbrel >> 4) & 0x0F, + descdev->vendorid, descdev->prodid, descdev->configcnt); + + grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); + + for (i = 0; i < descdev->configcnt; i++) + { + struct grub_usb_desc_config *config; + + config = dev->config[i].descconf; + usb_print_str ("Configuration:", dev, config->strconfig); + } + + for (i = 0; i < dev->config[0].descconf->numif; i++) + { + int j; + struct grub_usb_desc_if *interf; + interf = dev->config[0].interf[i].descif; + + grub_printf ("Interface #%d: #Endpoints: %d ", + i, interf->endpointcnt); + if (interf->class > 0 && interf->class <= 0x0E) + grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n", + interf->class, usb_classes[interf->class], + interf->subclass, interf->protocol); + + usb_print_str ("Interface", dev, interf->strif); + + for (j = 0; j < interf->endpointcnt; j++) + { + struct grub_usb_desc_endp *endp; + endp = &dev->config[0].interf[i].descendp[j]; + + grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n", + endp->endp_addr & 15, + (endp->endp_addr & 128) ? "IN" : "OUT", + endp->maxpacket, usb_endp_type[endp->attrib & 3], + endp->interval); + } + } + + grub_printf("\n"); + + return 0; +} + +static grub_err_t +grub_cmd_usbtest (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_printf ("USB devices:\n\n"); + grub_usb_iterate (usb_iterate); + + return 0; +} + +GRUB_MOD_INIT(usbtest) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("usb", grub_cmd_usbtest, GRUB_COMMAND_FLAG_BOTH, + "usb", "Test USB support", 0); +} + +GRUB_MOD_FINI(usbtest) +{ + grub_unregister_command ("usb"); +} diff --git a/commands/videotest.c b/commands/videotest.c new file mode 100644 index 0000000..a9ead81 --- /dev/null +++ b/commands/videotest.c @@ -0,0 +1,191 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_videotest (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + if (grub_video_setup (1024, 768, + GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE) + return grub_errno; + + grub_video_color_t color; + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + int i; + grub_font_t sansbig; + grub_font_t sans; + grub_font_t sanssmall; + grub_font_t fixed; + struct grub_font_glyph *glyph; + struct grub_video_render_target *text_layer; + grub_video_color_t palette[16]; + const char *str; + int texty; + + grub_video_get_viewport (&x, &y, &width, &height); + + grub_video_create_render_target (&text_layer, width, height, + GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA); + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + color = grub_video_map_rgb (0, 0, 0); + grub_video_fill_rect (color, 0, 0, width, height); + + color = grub_video_map_rgb (255, 0, 0); + grub_video_fill_rect (color, 0, 0, 100, 100); + + color = grub_video_map_rgb (0, 255, 255); + grub_video_fill_rect (color, 100, 100, 100, 100); + + sansbig = grub_font_get ("Helvetica Bold 24"); + sans = grub_font_get ("Helvetica Bold 14"); + sanssmall = grub_font_get ("Helvetica 8"); + fixed = grub_font_get ("Fixed 20"); + if (! sansbig || ! sans || ! sanssmall || ! fixed) + return grub_error (GRUB_ERR_BAD_FONT, "No font loaded."); + + glyph = grub_font_get_glyph (fixed, '*'); + grub_font_draw_glyph (glyph, color, 200 ,0); + + grub_video_set_viewport (x + 150, y + 150, + width - 150 * 2, height - 150 * 2); + color = grub_video_map_rgb (77, 33, 77); + grub_video_fill_rect (color, 0, 0, width, height); + + grub_video_set_active_render_target (text_layer); + + color = grub_video_map_rgb (255, 255, 255); + + texty = 32; + grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", + sans, color, 16, texty); + texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); + + texty += grub_font_get_ascent (fixed); + grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", + fixed, color, 16, texty); + texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); + + /* To convert Unicode characters into UTF-8 for this test, the following + command is useful: + echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1 + This converts the Unicode character U+263A to UTF-8. */ + + /* Characters used: + Code point Description UTF-8 encoding + ----------- ------------------------------ -------------- + U+263A unfilled smiley face E2 98 BA + U+00A1 inverted exclamation point C2 A1 + U+00A3 British pound currency symbol C2 A3 + U+03C4 Greek tau CF 84 + U+00E4 lowercase letter a with umlaut C3 A4 + U+2124 set 'Z' symbol (integers) E2 84 A4 + U+2287 subset symbol E2 8A 87 + U+211D set 'R' symbol (real numbers) E2 84 9D */ + + str = + "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00" + " \xC2\xA1\xCF\x84\xC3\xA4u! " + " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D"; + color = grub_video_map_rgb (128, 128, 255); + + /* All characters in the string exist in the 'Fixed 20' (10x20) font. */ + texty += grub_font_get_ascent(fixed); + grub_font_draw_string (str, fixed, color, 16, texty); + texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); + + /* Some character don't exist in the Helvetica font, so the font engine + will fall back to using glyphs from another font that does contain them. + TODO The font engine should be smart about selecting a replacement font + and prioritize fonts with similar sizes. */ + + texty += grub_font_get_ascent(sansbig); + grub_font_draw_string (str, sansbig, color, 16, texty); + texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig); + + texty += grub_font_get_ascent(sans); + grub_font_draw_string (str, sans, color, 16, texty); + texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); + + texty += grub_font_get_ascent(sanssmall); + grub_font_draw_string (str, sanssmall, color, 16, texty); + texty += (grub_font_get_descent (sanssmall) + + grub_font_get_leading (sanssmall)); + + glyph = grub_font_get_glyph (fixed, '*'); + + for (i = 0; i < 16; i++) + { + color = grub_video_map_color (i); + palette[i] = color; + grub_font_draw_glyph (glyph, color, 16 + i * 16, 220); + } + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + for (i = 0; i < 255; i++) + { + color = grub_video_map_rgb (i, 33, 77); + grub_video_fill_rect (color, 0, 0, width, height); + grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0, + 0, 0, width, height); + } + + grub_getkey (); + + grub_video_delete_render_target (text_layer); + + grub_video_restore (); + + for (i = 0; i < 16; i++) + grub_printf("color %d: %08x\n", i, palette[i]); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + +GRUB_MOD_INIT(videotest) +{ + grub_register_command ("videotest", + grub_cmd_videotest, + GRUB_COMMAND_FLAG_BOTH, + "videotest", + "Test video subsystem", + 0); +} + +GRUB_MOD_FINI(videotest) +{ + grub_unregister_command ("videotest"); +} diff --git a/conf/common.mk b/conf/common.mk new file mode 100644 index 0000000..9b67944 --- /dev/null +++ b/conf/common.mk @@ -0,0 +1,4303 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +# For grub-mkelfimage. +bin_UTILITIES += grub-mkelfimage +grub_mkelfimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \ + util/resolve.c +CLEANFILES += grub-mkelfimage$(EXEEXT) grub_mkelfimage-util_elf_grub_mkimage.o grub_mkelfimage-util_misc.o grub_mkelfimage-util_resolve.o +MOSTLYCLEANFILES += grub_mkelfimage-util_elf_grub_mkimage.d grub_mkelfimage-util_misc.d grub_mkelfimage-util_resolve.d + +grub-mkelfimage: $(grub_mkelfimage_DEPENDENCIES) grub_mkelfimage-util_elf_grub_mkimage.o grub_mkelfimage-util_misc.o grub_mkelfimage-util_resolve.o + $(CC) -o $@ grub_mkelfimage-util_elf_grub_mkimage.o grub_mkelfimage-util_misc.o grub_mkelfimage-util_resolve.o $(LDFLAGS) $(grub_mkelfimage_LDFLAGS) + +grub_mkelfimage-util_elf_grub_mkimage.o: util/elf/grub-mkimage.c $(util/elf/grub-mkimage.c_DEPENDENCIES) + $(CC) -Iutil/elf -I$(srcdir)/util/elf $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkelfimage-util_elf_grub_mkimage.d + +grub_mkelfimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkelfimage-util_misc.d + +grub_mkelfimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkelfimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkelfimage-util_resolve.d + +util/elf/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-probe. +sbin_UTILITIES += grub-probe +util/grub-probe.c_DEPENDENCIES = grub_probe_init.h +grub_probe_SOURCES = util/grub-probe.c \ + util/hostdisk.c util/misc.c util/getroot.c \ + kern/device.c kern/disk.c kern/err.c kern/misc.c \ + kern/parser.c kern/partition.c kern/file.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + partmap/pc.c partmap/apple.c partmap/gpt.c \ + kern/fs.c kern/env.c fs/fshelp.c \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c +CLEANFILES += grub-probe$(EXEEXT) grub_probe-util_grub_probe.o grub_probe-util_hostdisk.o grub_probe-util_misc.o grub_probe-util_getroot.o grub_probe-kern_device.o grub_probe-kern_disk.o grub_probe-kern_err.o grub_probe-kern_misc.o grub_probe-kern_parser.o grub_probe-kern_partition.o grub_probe-kern_file.o grub_probe-fs_affs.o grub_probe-fs_cpio.o grub_probe-fs_fat.o grub_probe-fs_ext2.o grub_probe-fs_hfs.o grub_probe-fs_hfsplus.o grub_probe-fs_iso9660.o grub_probe-fs_udf.o grub_probe-fs_jfs.o grub_probe-fs_minix.o grub_probe-fs_ntfs.o grub_probe-fs_ntfscomp.o grub_probe-fs_reiserfs.o grub_probe-fs_sfs.o grub_probe-fs_ufs.o grub_probe-fs_xfs.o grub_probe-fs_afs.o grub_probe-fs_tar.o grub_probe-partmap_pc.o grub_probe-partmap_apple.o grub_probe-partmap_gpt.o grub_probe-kern_fs.o grub_probe-kern_env.o grub_probe-fs_fshelp.o grub_probe-disk_raid.o grub_probe-disk_mdraid_linux.o grub_probe-disk_lvm.o grub_probe-grub_probe_init.o +MOSTLYCLEANFILES += grub_probe-util_grub_probe.d grub_probe-util_hostdisk.d grub_probe-util_misc.d grub_probe-util_getroot.d grub_probe-kern_device.d grub_probe-kern_disk.d grub_probe-kern_err.d grub_probe-kern_misc.d grub_probe-kern_parser.d grub_probe-kern_partition.d grub_probe-kern_file.d grub_probe-fs_affs.d grub_probe-fs_cpio.d grub_probe-fs_fat.d grub_probe-fs_ext2.d grub_probe-fs_hfs.d grub_probe-fs_hfsplus.d grub_probe-fs_iso9660.d grub_probe-fs_udf.d grub_probe-fs_jfs.d grub_probe-fs_minix.d grub_probe-fs_ntfs.d grub_probe-fs_ntfscomp.d grub_probe-fs_reiserfs.d grub_probe-fs_sfs.d grub_probe-fs_ufs.d grub_probe-fs_xfs.d grub_probe-fs_afs.d grub_probe-fs_tar.d grub_probe-partmap_pc.d grub_probe-partmap_apple.d grub_probe-partmap_gpt.d grub_probe-kern_fs.d grub_probe-kern_env.d grub_probe-fs_fshelp.d grub_probe-disk_raid.d grub_probe-disk_mdraid_linux.d grub_probe-disk_lvm.d grub_probe-grub_probe_init.d + +grub-probe: $(grub_probe_DEPENDENCIES) grub_probe-util_grub_probe.o grub_probe-util_hostdisk.o grub_probe-util_misc.o grub_probe-util_getroot.o grub_probe-kern_device.o grub_probe-kern_disk.o grub_probe-kern_err.o grub_probe-kern_misc.o grub_probe-kern_parser.o grub_probe-kern_partition.o grub_probe-kern_file.o grub_probe-fs_affs.o grub_probe-fs_cpio.o grub_probe-fs_fat.o grub_probe-fs_ext2.o grub_probe-fs_hfs.o grub_probe-fs_hfsplus.o grub_probe-fs_iso9660.o grub_probe-fs_udf.o grub_probe-fs_jfs.o grub_probe-fs_minix.o grub_probe-fs_ntfs.o grub_probe-fs_ntfscomp.o grub_probe-fs_reiserfs.o grub_probe-fs_sfs.o grub_probe-fs_ufs.o grub_probe-fs_xfs.o grub_probe-fs_afs.o grub_probe-fs_tar.o grub_probe-partmap_pc.o grub_probe-partmap_apple.o grub_probe-partmap_gpt.o grub_probe-kern_fs.o grub_probe-kern_env.o grub_probe-fs_fshelp.o grub_probe-disk_raid.o grub_probe-disk_mdraid_linux.o grub_probe-disk_lvm.o grub_probe-grub_probe_init.o + $(CC) -o $@ grub_probe-util_grub_probe.o grub_probe-util_hostdisk.o grub_probe-util_misc.o grub_probe-util_getroot.o grub_probe-kern_device.o grub_probe-kern_disk.o grub_probe-kern_err.o grub_probe-kern_misc.o grub_probe-kern_parser.o grub_probe-kern_partition.o grub_probe-kern_file.o grub_probe-fs_affs.o grub_probe-fs_cpio.o grub_probe-fs_fat.o grub_probe-fs_ext2.o grub_probe-fs_hfs.o grub_probe-fs_hfsplus.o grub_probe-fs_iso9660.o grub_probe-fs_udf.o grub_probe-fs_jfs.o grub_probe-fs_minix.o grub_probe-fs_ntfs.o grub_probe-fs_ntfscomp.o grub_probe-fs_reiserfs.o grub_probe-fs_sfs.o grub_probe-fs_ufs.o grub_probe-fs_xfs.o grub_probe-fs_afs.o grub_probe-fs_tar.o grub_probe-partmap_pc.o grub_probe-partmap_apple.o grub_probe-partmap_gpt.o grub_probe-kern_fs.o grub_probe-kern_env.o grub_probe-fs_fshelp.o grub_probe-disk_raid.o grub_probe-disk_mdraid_linux.o grub_probe-disk_lvm.o grub_probe-grub_probe_init.o $(LDFLAGS) $(grub_probe_LDFLAGS) + +grub_probe-util_grub_probe.o: util/grub-probe.c $(util/grub-probe.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-util_grub_probe.d + +grub_probe-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-util_hostdisk.d + +grub_probe-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-util_misc.d + +grub_probe-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-util_getroot.d + +grub_probe-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_device.d + +grub_probe-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_disk.d + +grub_probe-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_err.d + +grub_probe-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_misc.d + +grub_probe-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_parser.d + +grub_probe-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_partition.d + +grub_probe-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_file.d + +grub_probe-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_affs.d + +grub_probe-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_cpio.d + +grub_probe-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_fat.d + +grub_probe-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_ext2.d + +grub_probe-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_hfs.d + +grub_probe-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_hfsplus.d + +grub_probe-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_iso9660.d + +grub_probe-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_udf.d + +grub_probe-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_jfs.d + +grub_probe-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_minix.d + +grub_probe-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_ntfs.d + +grub_probe-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_ntfscomp.d + +grub_probe-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_reiserfs.d + +grub_probe-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_sfs.d + +grub_probe-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_ufs.d + +grub_probe-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_xfs.d + +grub_probe-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_afs.d + +grub_probe-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_tar.d + +grub_probe-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-partmap_pc.d + +grub_probe-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-partmap_apple.d + +grub_probe-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-partmap_gpt.d + +grub_probe-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_fs.d + +grub_probe-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-kern_env.d + +grub_probe-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-fs_fshelp.d + +grub_probe-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-disk_raid.d + +grub_probe-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-disk_mdraid_linux.d + +grub_probe-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-disk_lvm.d + +grub_probe-grub_probe_init.o: grub_probe_init.c $(grub_probe_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_probe_CFLAGS) -MD -c -o $@ $< +-include grub_probe-grub_probe_init.d + + +ifeq ($(enable_grub_fstest), yes) +bin_UTILITIES += grub-fstest +endif + +# For grub-fstest. +util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h +grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c \ + kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ + disk/host.c disk/loopback.c normal/arg.c normal/misc.c \ + lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + kern/partition.c partmap/pc.c partmap/apple.c partmap/gpt.c \ + kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \ + disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_fstest_init.c +CLEANFILES += grub-fstest$(EXEEXT) grub_fstest-util_grub_fstest.o grub_fstest-util_hostfs.o grub_fstest-util_misc.o grub_fstest-kern_file.o grub_fstest-kern_device.o grub_fstest-kern_disk.o grub_fstest-kern_err.o grub_fstest-kern_misc.o grub_fstest-disk_host.o grub_fstest-disk_loopback.o grub_fstest-normal_arg.o grub_fstest-normal_misc.o grub_fstest-lib_hexdump.o grub_fstest-lib_crc.o grub_fstest-commands_blocklist.o grub_fstest-commands_ls.o grub_fstest-fs_affs.o grub_fstest-fs_cpio.o grub_fstest-fs_fat.o grub_fstest-fs_ext2.o grub_fstest-fs_hfs.o grub_fstest-fs_hfsplus.o grub_fstest-fs_iso9660.o grub_fstest-fs_udf.o grub_fstest-fs_jfs.o grub_fstest-fs_minix.o grub_fstest-fs_ntfs.o grub_fstest-fs_ntfscomp.o grub_fstest-fs_reiserfs.o grub_fstest-fs_sfs.o grub_fstest-fs_ufs.o grub_fstest-fs_xfs.o grub_fstest-fs_afs.o grub_fstest-fs_tar.o grub_fstest-kern_partition.o grub_fstest-partmap_pc.o grub_fstest-partmap_apple.o grub_fstest-partmap_gpt.o grub_fstest-kern_fs.o grub_fstest-kern_env.o grub_fstest-fs_fshelp.o grub_fstest-disk_raid.o grub_fstest-disk_raid5_recover.o grub_fstest-disk_raid6_recover.o grub_fstest-disk_mdraid_linux.o grub_fstest-disk_dmraid_nvidia.o grub_fstest-disk_lvm.o grub_fstest-grub_fstest_init.o +MOSTLYCLEANFILES += grub_fstest-util_grub_fstest.d grub_fstest-util_hostfs.d grub_fstest-util_misc.d grub_fstest-kern_file.d grub_fstest-kern_device.d grub_fstest-kern_disk.d grub_fstest-kern_err.d grub_fstest-kern_misc.d grub_fstest-disk_host.d grub_fstest-disk_loopback.d grub_fstest-normal_arg.d grub_fstest-normal_misc.d grub_fstest-lib_hexdump.d grub_fstest-lib_crc.d grub_fstest-commands_blocklist.d grub_fstest-commands_ls.d grub_fstest-fs_affs.d grub_fstest-fs_cpio.d grub_fstest-fs_fat.d grub_fstest-fs_ext2.d grub_fstest-fs_hfs.d grub_fstest-fs_hfsplus.d grub_fstest-fs_iso9660.d grub_fstest-fs_udf.d grub_fstest-fs_jfs.d grub_fstest-fs_minix.d grub_fstest-fs_ntfs.d grub_fstest-fs_ntfscomp.d grub_fstest-fs_reiserfs.d grub_fstest-fs_sfs.d grub_fstest-fs_ufs.d grub_fstest-fs_xfs.d grub_fstest-fs_afs.d grub_fstest-fs_tar.d grub_fstest-kern_partition.d grub_fstest-partmap_pc.d grub_fstest-partmap_apple.d grub_fstest-partmap_gpt.d grub_fstest-kern_fs.d grub_fstest-kern_env.d grub_fstest-fs_fshelp.d grub_fstest-disk_raid.d grub_fstest-disk_raid5_recover.d grub_fstest-disk_raid6_recover.d grub_fstest-disk_mdraid_linux.d grub_fstest-disk_dmraid_nvidia.d grub_fstest-disk_lvm.d grub_fstest-grub_fstest_init.d + +grub-fstest: $(grub_fstest_DEPENDENCIES) grub_fstest-util_grub_fstest.o grub_fstest-util_hostfs.o grub_fstest-util_misc.o grub_fstest-kern_file.o grub_fstest-kern_device.o grub_fstest-kern_disk.o grub_fstest-kern_err.o grub_fstest-kern_misc.o grub_fstest-disk_host.o grub_fstest-disk_loopback.o grub_fstest-normal_arg.o grub_fstest-normal_misc.o grub_fstest-lib_hexdump.o grub_fstest-lib_crc.o grub_fstest-commands_blocklist.o grub_fstest-commands_ls.o grub_fstest-fs_affs.o grub_fstest-fs_cpio.o grub_fstest-fs_fat.o grub_fstest-fs_ext2.o grub_fstest-fs_hfs.o grub_fstest-fs_hfsplus.o grub_fstest-fs_iso9660.o grub_fstest-fs_udf.o grub_fstest-fs_jfs.o grub_fstest-fs_minix.o grub_fstest-fs_ntfs.o grub_fstest-fs_ntfscomp.o grub_fstest-fs_reiserfs.o grub_fstest-fs_sfs.o grub_fstest-fs_ufs.o grub_fstest-fs_xfs.o grub_fstest-fs_afs.o grub_fstest-fs_tar.o grub_fstest-kern_partition.o grub_fstest-partmap_pc.o grub_fstest-partmap_apple.o grub_fstest-partmap_gpt.o grub_fstest-kern_fs.o grub_fstest-kern_env.o grub_fstest-fs_fshelp.o grub_fstest-disk_raid.o grub_fstest-disk_raid5_recover.o grub_fstest-disk_raid6_recover.o grub_fstest-disk_mdraid_linux.o grub_fstest-disk_dmraid_nvidia.o grub_fstest-disk_lvm.o grub_fstest-grub_fstest_init.o + $(CC) -o $@ grub_fstest-util_grub_fstest.o grub_fstest-util_hostfs.o grub_fstest-util_misc.o grub_fstest-kern_file.o grub_fstest-kern_device.o grub_fstest-kern_disk.o grub_fstest-kern_err.o grub_fstest-kern_misc.o grub_fstest-disk_host.o grub_fstest-disk_loopback.o grub_fstest-normal_arg.o grub_fstest-normal_misc.o grub_fstest-lib_hexdump.o grub_fstest-lib_crc.o grub_fstest-commands_blocklist.o grub_fstest-commands_ls.o grub_fstest-fs_affs.o grub_fstest-fs_cpio.o grub_fstest-fs_fat.o grub_fstest-fs_ext2.o grub_fstest-fs_hfs.o grub_fstest-fs_hfsplus.o grub_fstest-fs_iso9660.o grub_fstest-fs_udf.o grub_fstest-fs_jfs.o grub_fstest-fs_minix.o grub_fstest-fs_ntfs.o grub_fstest-fs_ntfscomp.o grub_fstest-fs_reiserfs.o grub_fstest-fs_sfs.o grub_fstest-fs_ufs.o grub_fstest-fs_xfs.o grub_fstest-fs_afs.o grub_fstest-fs_tar.o grub_fstest-kern_partition.o grub_fstest-partmap_pc.o grub_fstest-partmap_apple.o grub_fstest-partmap_gpt.o grub_fstest-kern_fs.o grub_fstest-kern_env.o grub_fstest-fs_fshelp.o grub_fstest-disk_raid.o grub_fstest-disk_raid5_recover.o grub_fstest-disk_raid6_recover.o grub_fstest-disk_mdraid_linux.o grub_fstest-disk_dmraid_nvidia.o grub_fstest-disk_lvm.o grub_fstest-grub_fstest_init.o $(LDFLAGS) $(grub_fstest_LDFLAGS) + +grub_fstest-util_grub_fstest.o: util/grub-fstest.c $(util/grub-fstest.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-util_grub_fstest.d + +grub_fstest-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-util_hostfs.d + +grub_fstest-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-util_misc.d + +grub_fstest-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_file.d + +grub_fstest-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_device.d + +grub_fstest-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_disk.d + +grub_fstest-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_err.d + +grub_fstest-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_misc.d + +grub_fstest-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_host.d + +grub_fstest-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_loopback.d + +grub_fstest-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-normal_arg.d + +grub_fstest-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-normal_misc.d + +grub_fstest-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-lib_hexdump.d + +grub_fstest-lib_crc.o: lib/crc.c $(lib/crc.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-lib_crc.d + +grub_fstest-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-commands_blocklist.d + +grub_fstest-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-commands_ls.d + +grub_fstest-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_affs.d + +grub_fstest-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_cpio.d + +grub_fstest-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_fat.d + +grub_fstest-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_ext2.d + +grub_fstest-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_hfs.d + +grub_fstest-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_hfsplus.d + +grub_fstest-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_iso9660.d + +grub_fstest-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_udf.d + +grub_fstest-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_jfs.d + +grub_fstest-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_minix.d + +grub_fstest-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_ntfs.d + +grub_fstest-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_ntfscomp.d + +grub_fstest-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_reiserfs.d + +grub_fstest-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_sfs.d + +grub_fstest-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_ufs.d + +grub_fstest-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_xfs.d + +grub_fstest-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_afs.d + +grub_fstest-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_tar.d + +grub_fstest-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_partition.d + +grub_fstest-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-partmap_pc.d + +grub_fstest-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-partmap_apple.d + +grub_fstest-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-partmap_gpt.d + +grub_fstest-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_fs.d + +grub_fstest-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-kern_env.d + +grub_fstest-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-fs_fshelp.d + +grub_fstest-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_raid.d + +grub_fstest-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_raid5_recover.d + +grub_fstest-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_raid6_recover.d + +grub_fstest-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_mdraid_linux.d + +grub_fstest-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_dmraid_nvidia.d + +grub_fstest-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-disk_lvm.d + +grub_fstest-grub_fstest_init.o: grub_fstest_init.c $(grub_fstest_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_fstest_CFLAGS) -MD -c -o $@ $< +-include grub_fstest-grub_fstest_init.d + + +# For grub-mkfont. +ifeq ($(enable_grub_mkfont), yes) +bin_UTILITIES += grub-mkfont +grub_mkfont_SOURCES = util/grub-mkfont.c util/misc.c +CLEANFILES += grub-mkfont$(EXEEXT) grub_mkfont-util_grub_mkfont.o grub_mkfont-util_misc.o +MOSTLYCLEANFILES += grub_mkfont-util_grub_mkfont.d grub_mkfont-util_misc.d + +grub-mkfont: $(grub_mkfont_DEPENDENCIES) grub_mkfont-util_grub_mkfont.o grub_mkfont-util_misc.o + $(CC) -o $@ grub_mkfont-util_grub_mkfont.o grub_mkfont-util_misc.o $(LDFLAGS) $(grub_mkfont_LDFLAGS) + +grub_mkfont-util_grub_mkfont.o: util/grub-mkfont.c $(util/grub-mkfont.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkfont_CFLAGS) -MD -c -o $@ $< +-include grub_mkfont-util_grub_mkfont.d + +grub_mkfont-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkfont_CFLAGS) -MD -c -o $@ $< +-include grub_mkfont-util_misc.d + +grub_mkfont_CFLAGS = $(freetype_cflags) +grub_mkfont_LDFLAGS = $(freetype_libs) +endif + +# For the parser. +grub_script.tab.c grub_script.tab.h: normal/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y +DISTCLEANFILES += grub_script.tab.c grub_script.tab.h + +# For grub-emu. +grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_emu_init.lst + +grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_emu_init.h + +grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_emu_init.c + +# For grub-probe. +grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_probe_init.lst + +grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_probe_init.h + +grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_probe_init.c + +# For grub-setup. +grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_setup_init.lst + +grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_setup_init.h + +grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_setup_init.c + +# For grub-fstest. +grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_fstest_init.lst + +grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_fstest_init.h + +grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_fstest_init.c + +# for grub-editenv +bin_UTILITIES += grub-editenv +grub_editenv_SOURCES = util/grub-editenv.c lib/envblk.c util/misc.c kern/misc.c kern/err.c +CLEANFILES += grub-editenv$(EXEEXT) grub_editenv-util_grub_editenv.o grub_editenv-lib_envblk.o grub_editenv-util_misc.o grub_editenv-kern_misc.o grub_editenv-kern_err.o +MOSTLYCLEANFILES += grub_editenv-util_grub_editenv.d grub_editenv-lib_envblk.d grub_editenv-util_misc.d grub_editenv-kern_misc.d grub_editenv-kern_err.d + +grub-editenv: $(grub_editenv_DEPENDENCIES) grub_editenv-util_grub_editenv.o grub_editenv-lib_envblk.o grub_editenv-util_misc.o grub_editenv-kern_misc.o grub_editenv-kern_err.o + $(CC) -o $@ grub_editenv-util_grub_editenv.o grub_editenv-lib_envblk.o grub_editenv-util_misc.o grub_editenv-kern_misc.o grub_editenv-kern_err.o $(LDFLAGS) $(grub_editenv_LDFLAGS) + +grub_editenv-util_grub_editenv.o: util/grub-editenv.c $(util/grub-editenv.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $< +-include grub_editenv-util_grub_editenv.d + +grub_editenv-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $< +-include grub_editenv-lib_envblk.d + +grub_editenv-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $< +-include grub_editenv-util_misc.d + +grub_editenv-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $< +-include grub_editenv-kern_misc.d + +grub_editenv-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_editenv_CFLAGS) -MD -c -o $@ $< +-include grub_editenv-kern_err.d + +CLEANFILES += grub-editenv + +# for grub-pe2elf +ifeq ($(enable_grub_pe2elf), yes) +bin_UTILITIES += grub-pe2elf +endif + +grub_pe2elf_SOURCES = util/grub-pe2elf.c util/misc.c +CLEANFILES += grub-pe2elf$(EXEEXT) grub_pe2elf-util_grub_pe2elf.o grub_pe2elf-util_misc.o +MOSTLYCLEANFILES += grub_pe2elf-util_grub_pe2elf.d grub_pe2elf-util_misc.d + +grub-pe2elf: $(grub_pe2elf_DEPENDENCIES) grub_pe2elf-util_grub_pe2elf.o grub_pe2elf-util_misc.o + $(CC) -o $@ grub_pe2elf-util_grub_pe2elf.o grub_pe2elf-util_misc.o $(LDFLAGS) $(grub_pe2elf_LDFLAGS) + +grub_pe2elf-util_grub_pe2elf.o: util/grub-pe2elf.c $(util/grub-pe2elf.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_pe2elf_CFLAGS) -MD -c -o $@ $< +-include grub_pe2elf-util_grub_pe2elf.d + +grub_pe2elf-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_pe2elf_CFLAGS) -MD -c -o $@ $< +-include grub_pe2elf-util_misc.d + +CLEANFILES += grub-pe2elf + +# For grub-mkconfig +grub-mkconfig: util/grub-mkconfig.in config.status + ./config.status --file=$@:$< + chmod +x $@ +sbin_SCRIPTS += grub-mkconfig +CLEANFILES += grub-mkconfig + +grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status + ./config.status --file=$@:$< + chmod +x $@ +lib_DATA += grub-mkconfig_lib +CLEANFILES += grub-mkconfig_lib + +update-grub_lib: util/update-grub_lib.in config.status + ./config.status --file=$@:$< + chmod +x $@ +lib_DATA += update-grub_lib +CLEANFILES += update-grub_lib + +%: util/grub.d/%.in config.status + ./config.status --file=$@:$< + chmod +x $@ +grub-mkconfig_SCRIPTS = 00_header 10_linux 10_hurd 10_freebsd 30_os-prober 40_custom +ifeq ($(host_os), cygwin) +grub-mkconfig_SCRIPTS += 10_windows +endif + +CLEANFILES += $(grub-mkconfig_SCRIPTS) + +grub-mkconfig_DATA += util/grub.d/README + + +# Filing systems. +pkglib_MODULES += fshelp.mod fat.mod ufs.mod ext2.mod ntfs.mod \ + ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod \ + affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod \ + udf.mod afs.mod + +# For fshelp.mod. +fshelp_mod_SOURCES = fs/fshelp.c +CLEANFILES += fshelp.mod mod-fshelp.o mod-fshelp.c pre-fshelp.o fshelp_mod-fs_fshelp.o und-fshelp.lst +ifneq ($(fshelp_mod_EXPORTS),no) +CLEANFILES += def-fshelp.lst +DEFSYMFILES += def-fshelp.lst +endif +MOSTLYCLEANFILES += fshelp_mod-fs_fshelp.d +UNDSYMFILES += und-fshelp.lst + +fshelp.mod: pre-fshelp.o mod-fshelp.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-fshelp.o mod-fshelp.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-fshelp.o: $(fshelp_mod_DEPENDENCIES) fshelp_mod-fs_fshelp.o + -rm -f $@ + $(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fshelp_mod-fs_fshelp.o + +mod-fshelp.o: mod-fshelp.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -c -o $@ $< + +mod-fshelp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fshelp' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(fshelp_mod_EXPORTS),no) +def-fshelp.lst: pre-fshelp.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fshelp/' > $@ +endif + +und-fshelp.lst: pre-fshelp.o + echo 'fshelp' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +fshelp_mod-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -MD -c -o $@ $< +-include fshelp_mod-fs_fshelp.d + +CLEANFILES += cmd-fshelp_mod-fs_fshelp.lst fs-fshelp_mod-fs_fshelp.lst partmap-fshelp_mod-fs_fshelp.lst +COMMANDFILES += cmd-fshelp_mod-fs_fshelp.lst +FSFILES += fs-fshelp_mod-fs_fshelp.lst +PARTMAPFILES += partmap-fshelp_mod-fs_fshelp.lst + +cmd-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh fshelp > $@ || (rm -f $@; exit 1) + +fs-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh fshelp > $@ || (rm -f $@; exit 1) + +partmap-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh fshelp > $@ || (rm -f $@; exit 1) + + +fshelp_mod_CFLAGS = $(COMMON_CFLAGS) +fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +CLEANFILES += fat.mod mod-fat.o mod-fat.c pre-fat.o fat_mod-fs_fat.o und-fat.lst +ifneq ($(fat_mod_EXPORTS),no) +CLEANFILES += def-fat.lst +DEFSYMFILES += def-fat.lst +endif +MOSTLYCLEANFILES += fat_mod-fs_fat.d +UNDSYMFILES += und-fat.lst + +fat.mod: pre-fat.o mod-fat.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-fat.o mod-fat.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-fat.o: $(fat_mod_DEPENDENCIES) fat_mod-fs_fat.o + -rm -f $@ + $(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fat_mod-fs_fat.o + +mod-fat.o: mod-fat.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -c -o $@ $< + +mod-fat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fat' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(fat_mod_EXPORTS),no) +def-fat.lst: pre-fat.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fat/' > $@ +endif + +und-fat.lst: pre-fat.o + echo 'fat' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +fat_mod-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -MD -c -o $@ $< +-include fat_mod-fs_fat.d + +CLEANFILES += cmd-fat_mod-fs_fat.lst fs-fat_mod-fs_fat.lst partmap-fat_mod-fs_fat.lst +COMMANDFILES += cmd-fat_mod-fs_fat.lst +FSFILES += fs-fat_mod-fs_fat.lst +PARTMAPFILES += partmap-fat_mod-fs_fat.lst + +cmd-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh fat > $@ || (rm -f $@; exit 1) + +fs-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh fat > $@ || (rm -f $@; exit 1) + +partmap-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh fat > $@ || (rm -f $@; exit 1) + + +fat_mod_CFLAGS = $(COMMON_CFLAGS) +fat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ufs.mod. +ufs_mod_SOURCES = fs/ufs.c +CLEANFILES += ufs.mod mod-ufs.o mod-ufs.c pre-ufs.o ufs_mod-fs_ufs.o und-ufs.lst +ifneq ($(ufs_mod_EXPORTS),no) +CLEANFILES += def-ufs.lst +DEFSYMFILES += def-ufs.lst +endif +MOSTLYCLEANFILES += ufs_mod-fs_ufs.d +UNDSYMFILES += und-ufs.lst + +ufs.mod: pre-ufs.o mod-ufs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ufs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ufs.o mod-ufs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ufs.o: $(ufs_mod_DEPENDENCIES) ufs_mod-fs_ufs.o + -rm -f $@ + $(TARGET_CC) $(ufs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ufs_mod-fs_ufs.o + +mod-ufs.o: mod-ufs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -c -o $@ $< + +mod-ufs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ufs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ufs_mod_EXPORTS),no) +def-ufs.lst: pre-ufs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ufs/' > $@ +endif + +und-ufs.lst: pre-ufs.o + echo 'ufs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ufs_mod-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -MD -c -o $@ $< +-include ufs_mod-fs_ufs.d + +CLEANFILES += cmd-ufs_mod-fs_ufs.lst fs-ufs_mod-fs_ufs.lst partmap-ufs_mod-fs_ufs.lst +COMMANDFILES += cmd-ufs_mod-fs_ufs.lst +FSFILES += fs-ufs_mod-fs_ufs.lst +PARTMAPFILES += partmap-ufs_mod-fs_ufs.lst + +cmd-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ufs > $@ || (rm -f $@; exit 1) + +fs-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ufs > $@ || (rm -f $@; exit 1) + +partmap-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ufs > $@ || (rm -f $@; exit 1) + + +ufs_mod_CFLAGS = $(COMMON_CFLAGS) +ufs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ext2.mod. +ext2_mod_SOURCES = fs/ext2.c +CLEANFILES += ext2.mod mod-ext2.o mod-ext2.c pre-ext2.o ext2_mod-fs_ext2.o und-ext2.lst +ifneq ($(ext2_mod_EXPORTS),no) +CLEANFILES += def-ext2.lst +DEFSYMFILES += def-ext2.lst +endif +MOSTLYCLEANFILES += ext2_mod-fs_ext2.d +UNDSYMFILES += und-ext2.lst + +ext2.mod: pre-ext2.o mod-ext2.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ext2.o mod-ext2.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ext2.o: $(ext2_mod_DEPENDENCIES) ext2_mod-fs_ext2.o + -rm -f $@ + $(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ext2_mod-fs_ext2.o + +mod-ext2.o: mod-ext2.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -c -o $@ $< + +mod-ext2.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ext2' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ext2_mod_EXPORTS),no) +def-ext2.lst: pre-ext2.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ext2/' > $@ +endif + +und-ext2.lst: pre-ext2.o + echo 'ext2' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ext2_mod-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -MD -c -o $@ $< +-include ext2_mod-fs_ext2.d + +CLEANFILES += cmd-ext2_mod-fs_ext2.lst fs-ext2_mod-fs_ext2.lst partmap-ext2_mod-fs_ext2.lst +COMMANDFILES += cmd-ext2_mod-fs_ext2.lst +FSFILES += fs-ext2_mod-fs_ext2.lst +PARTMAPFILES += partmap-ext2_mod-fs_ext2.lst + +cmd-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ext2 > $@ || (rm -f $@; exit 1) + +fs-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ext2 > $@ || (rm -f $@; exit 1) + +partmap-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ext2 > $@ || (rm -f $@; exit 1) + + +ext2_mod_CFLAGS = $(COMMON_CFLAGS) +ext2_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ntfs.mod. +ntfs_mod_SOURCES = fs/ntfs.c +CLEANFILES += ntfs.mod mod-ntfs.o mod-ntfs.c pre-ntfs.o ntfs_mod-fs_ntfs.o und-ntfs.lst +ifneq ($(ntfs_mod_EXPORTS),no) +CLEANFILES += def-ntfs.lst +DEFSYMFILES += def-ntfs.lst +endif +MOSTLYCLEANFILES += ntfs_mod-fs_ntfs.d +UNDSYMFILES += und-ntfs.lst + +ntfs.mod: pre-ntfs.o mod-ntfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ntfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ntfs.o mod-ntfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ntfs.o: $(ntfs_mod_DEPENDENCIES) ntfs_mod-fs_ntfs.o + -rm -f $@ + $(TARGET_CC) $(ntfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ntfs_mod-fs_ntfs.o + +mod-ntfs.o: mod-ntfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -c -o $@ $< + +mod-ntfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ntfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ntfs_mod_EXPORTS),no) +def-ntfs.lst: pre-ntfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ntfs/' > $@ +endif + +und-ntfs.lst: pre-ntfs.o + echo 'ntfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ntfs_mod-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -MD -c -o $@ $< +-include ntfs_mod-fs_ntfs.d + +CLEANFILES += cmd-ntfs_mod-fs_ntfs.lst fs-ntfs_mod-fs_ntfs.lst partmap-ntfs_mod-fs_ntfs.lst +COMMANDFILES += cmd-ntfs_mod-fs_ntfs.lst +FSFILES += fs-ntfs_mod-fs_ntfs.lst +PARTMAPFILES += partmap-ntfs_mod-fs_ntfs.lst + +cmd-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ntfs > $@ || (rm -f $@; exit 1) + +fs-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ntfs > $@ || (rm -f $@; exit 1) + +partmap-ntfs_mod-fs_ntfs.lst: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ntfs > $@ || (rm -f $@; exit 1) + + +ntfs_mod_CFLAGS = $(COMMON_CFLAGS) +ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ntfscomp.mod. +ntfscomp_mod_SOURCES = fs/ntfscomp.c +CLEANFILES += ntfscomp.mod mod-ntfscomp.o mod-ntfscomp.c pre-ntfscomp.o ntfscomp_mod-fs_ntfscomp.o und-ntfscomp.lst +ifneq ($(ntfscomp_mod_EXPORTS),no) +CLEANFILES += def-ntfscomp.lst +DEFSYMFILES += def-ntfscomp.lst +endif +MOSTLYCLEANFILES += ntfscomp_mod-fs_ntfscomp.d +UNDSYMFILES += und-ntfscomp.lst + +ntfscomp.mod: pre-ntfscomp.o mod-ntfscomp.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ntfscomp_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ntfscomp.o mod-ntfscomp.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ntfscomp.o: $(ntfscomp_mod_DEPENDENCIES) ntfscomp_mod-fs_ntfscomp.o + -rm -f $@ + $(TARGET_CC) $(ntfscomp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ntfscomp_mod-fs_ntfscomp.o + +mod-ntfscomp.o: mod-ntfscomp.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -c -o $@ $< + +mod-ntfscomp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ntfscomp' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ntfscomp_mod_EXPORTS),no) +def-ntfscomp.lst: pre-ntfscomp.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ntfscomp/' > $@ +endif + +und-ntfscomp.lst: pre-ntfscomp.o + echo 'ntfscomp' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ntfscomp_mod-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -MD -c -o $@ $< +-include ntfscomp_mod-fs_ntfscomp.d + +CLEANFILES += cmd-ntfscomp_mod-fs_ntfscomp.lst fs-ntfscomp_mod-fs_ntfscomp.lst partmap-ntfscomp_mod-fs_ntfscomp.lst +COMMANDFILES += cmd-ntfscomp_mod-fs_ntfscomp.lst +FSFILES += fs-ntfscomp_mod-fs_ntfscomp.lst +PARTMAPFILES += partmap-ntfscomp_mod-fs_ntfscomp.lst + +cmd-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ntfscomp > $@ || (rm -f $@; exit 1) + +fs-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ntfscomp > $@ || (rm -f $@; exit 1) + +partmap-ntfscomp_mod-fs_ntfscomp.lst: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ntfscomp_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ntfscomp > $@ || (rm -f $@; exit 1) + + +ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS) +ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For minix.mod. +minix_mod_SOURCES = fs/minix.c +CLEANFILES += minix.mod mod-minix.o mod-minix.c pre-minix.o minix_mod-fs_minix.o und-minix.lst +ifneq ($(minix_mod_EXPORTS),no) +CLEANFILES += def-minix.lst +DEFSYMFILES += def-minix.lst +endif +MOSTLYCLEANFILES += minix_mod-fs_minix.d +UNDSYMFILES += und-minix.lst + +minix.mod: pre-minix.o mod-minix.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-minix.o mod-minix.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-minix.o: $(minix_mod_DEPENDENCIES) minix_mod-fs_minix.o + -rm -f $@ + $(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ minix_mod-fs_minix.o + +mod-minix.o: mod-minix.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -c -o $@ $< + +mod-minix.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'minix' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(minix_mod_EXPORTS),no) +def-minix.lst: pre-minix.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 minix/' > $@ +endif + +und-minix.lst: pre-minix.o + echo 'minix' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +minix_mod-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -MD -c -o $@ $< +-include minix_mod-fs_minix.d + +CLEANFILES += cmd-minix_mod-fs_minix.lst fs-minix_mod-fs_minix.lst partmap-minix_mod-fs_minix.lst +COMMANDFILES += cmd-minix_mod-fs_minix.lst +FSFILES += fs-minix_mod-fs_minix.lst +PARTMAPFILES += partmap-minix_mod-fs_minix.lst + +cmd-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh minix > $@ || (rm -f $@; exit 1) + +fs-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh minix > $@ || (rm -f $@; exit 1) + +partmap-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh minix > $@ || (rm -f $@; exit 1) + + +minix_mod_CFLAGS = $(COMMON_CFLAGS) +minix_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfs.mod. +hfs_mod_SOURCES = fs/hfs.c +CLEANFILES += hfs.mod mod-hfs.o mod-hfs.c pre-hfs.o hfs_mod-fs_hfs.o und-hfs.lst +ifneq ($(hfs_mod_EXPORTS),no) +CLEANFILES += def-hfs.lst +DEFSYMFILES += def-hfs.lst +endif +MOSTLYCLEANFILES += hfs_mod-fs_hfs.d +UNDSYMFILES += und-hfs.lst + +hfs.mod: pre-hfs.o mod-hfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hfs.o mod-hfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hfs.o: $(hfs_mod_DEPENDENCIES) hfs_mod-fs_hfs.o + -rm -f $@ + $(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hfs_mod-fs_hfs.o + +mod-hfs.o: mod-hfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -c -o $@ $< + +mod-hfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hfs_mod_EXPORTS),no) +def-hfs.lst: pre-hfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hfs/' > $@ +endif + +und-hfs.lst: pre-hfs.o + echo 'hfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hfs_mod-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -MD -c -o $@ $< +-include hfs_mod-fs_hfs.d + +CLEANFILES += cmd-hfs_mod-fs_hfs.lst fs-hfs_mod-fs_hfs.lst partmap-hfs_mod-fs_hfs.lst +COMMANDFILES += cmd-hfs_mod-fs_hfs.lst +FSFILES += fs-hfs_mod-fs_hfs.lst +PARTMAPFILES += partmap-hfs_mod-fs_hfs.lst + +cmd-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hfs > $@ || (rm -f $@; exit 1) + +fs-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hfs > $@ || (rm -f $@; exit 1) + +partmap-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hfs > $@ || (rm -f $@; exit 1) + + +hfs_mod_CFLAGS = $(COMMON_CFLAGS) +hfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jfs.mod. +jfs_mod_SOURCES = fs/jfs.c +CLEANFILES += jfs.mod mod-jfs.o mod-jfs.c pre-jfs.o jfs_mod-fs_jfs.o und-jfs.lst +ifneq ($(jfs_mod_EXPORTS),no) +CLEANFILES += def-jfs.lst +DEFSYMFILES += def-jfs.lst +endif +MOSTLYCLEANFILES += jfs_mod-fs_jfs.d +UNDSYMFILES += und-jfs.lst + +jfs.mod: pre-jfs.o mod-jfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-jfs.o mod-jfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-jfs.o: $(jfs_mod_DEPENDENCIES) jfs_mod-fs_jfs.o + -rm -f $@ + $(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ jfs_mod-fs_jfs.o + +mod-jfs.o: mod-jfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -c -o $@ $< + +mod-jfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'jfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(jfs_mod_EXPORTS),no) +def-jfs.lst: pre-jfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jfs/' > $@ +endif + +und-jfs.lst: pre-jfs.o + echo 'jfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +jfs_mod-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -MD -c -o $@ $< +-include jfs_mod-fs_jfs.d + +CLEANFILES += cmd-jfs_mod-fs_jfs.lst fs-jfs_mod-fs_jfs.lst partmap-jfs_mod-fs_jfs.lst +COMMANDFILES += cmd-jfs_mod-fs_jfs.lst +FSFILES += fs-jfs_mod-fs_jfs.lst +PARTMAPFILES += partmap-jfs_mod-fs_jfs.lst + +cmd-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh jfs > $@ || (rm -f $@; exit 1) + +fs-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh jfs > $@ || (rm -f $@; exit 1) + +partmap-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh jfs > $@ || (rm -f $@; exit 1) + + +jfs_mod_CFLAGS = $(COMMON_CFLAGS) +jfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For iso9660.mod. +iso9660_mod_SOURCES = fs/iso9660.c +CLEANFILES += iso9660.mod mod-iso9660.o mod-iso9660.c pre-iso9660.o iso9660_mod-fs_iso9660.o und-iso9660.lst +ifneq ($(iso9660_mod_EXPORTS),no) +CLEANFILES += def-iso9660.lst +DEFSYMFILES += def-iso9660.lst +endif +MOSTLYCLEANFILES += iso9660_mod-fs_iso9660.d +UNDSYMFILES += und-iso9660.lst + +iso9660.mod: pre-iso9660.o mod-iso9660.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(iso9660_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-iso9660.o mod-iso9660.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-iso9660.o: $(iso9660_mod_DEPENDENCIES) iso9660_mod-fs_iso9660.o + -rm -f $@ + $(TARGET_CC) $(iso9660_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ iso9660_mod-fs_iso9660.o + +mod-iso9660.o: mod-iso9660.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -c -o $@ $< + +mod-iso9660.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'iso9660' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(iso9660_mod_EXPORTS),no) +def-iso9660.lst: pre-iso9660.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 iso9660/' > $@ +endif + +und-iso9660.lst: pre-iso9660.o + echo 'iso9660' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +iso9660_mod-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -MD -c -o $@ $< +-include iso9660_mod-fs_iso9660.d + +CLEANFILES += cmd-iso9660_mod-fs_iso9660.lst fs-iso9660_mod-fs_iso9660.lst partmap-iso9660_mod-fs_iso9660.lst +COMMANDFILES += cmd-iso9660_mod-fs_iso9660.lst +FSFILES += fs-iso9660_mod-fs_iso9660.lst +PARTMAPFILES += partmap-iso9660_mod-fs_iso9660.lst + +cmd-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh iso9660 > $@ || (rm -f $@; exit 1) + +fs-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh iso9660 > $@ || (rm -f $@; exit 1) + +partmap-iso9660_mod-fs_iso9660.lst: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(iso9660_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh iso9660 > $@ || (rm -f $@; exit 1) + + +iso9660_mod_CFLAGS = $(COMMON_CFLAGS) +iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For xfs.mod. +xfs_mod_SOURCES = fs/xfs.c +CLEANFILES += xfs.mod mod-xfs.o mod-xfs.c pre-xfs.o xfs_mod-fs_xfs.o und-xfs.lst +ifneq ($(xfs_mod_EXPORTS),no) +CLEANFILES += def-xfs.lst +DEFSYMFILES += def-xfs.lst +endif +MOSTLYCLEANFILES += xfs_mod-fs_xfs.d +UNDSYMFILES += und-xfs.lst + +xfs.mod: pre-xfs.o mod-xfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-xfs.o mod-xfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-xfs.o: $(xfs_mod_DEPENDENCIES) xfs_mod-fs_xfs.o + -rm -f $@ + $(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xfs_mod-fs_xfs.o + +mod-xfs.o: mod-xfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -c -o $@ $< + +mod-xfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'xfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(xfs_mod_EXPORTS),no) +def-xfs.lst: pre-xfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xfs/' > $@ +endif + +und-xfs.lst: pre-xfs.o + echo 'xfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +xfs_mod-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -MD -c -o $@ $< +-include xfs_mod-fs_xfs.d + +CLEANFILES += cmd-xfs_mod-fs_xfs.lst fs-xfs_mod-fs_xfs.lst partmap-xfs_mod-fs_xfs.lst +COMMANDFILES += cmd-xfs_mod-fs_xfs.lst +FSFILES += fs-xfs_mod-fs_xfs.lst +PARTMAPFILES += partmap-xfs_mod-fs_xfs.lst + +cmd-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh xfs > $@ || (rm -f $@; exit 1) + +fs-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh xfs > $@ || (rm -f $@; exit 1) + +partmap-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh xfs > $@ || (rm -f $@; exit 1) + + +xfs_mod_CFLAGS = $(COMMON_CFLAGS) +xfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For affs.mod. +affs_mod_SOURCES = fs/affs.c +CLEANFILES += affs.mod mod-affs.o mod-affs.c pre-affs.o affs_mod-fs_affs.o und-affs.lst +ifneq ($(affs_mod_EXPORTS),no) +CLEANFILES += def-affs.lst +DEFSYMFILES += def-affs.lst +endif +MOSTLYCLEANFILES += affs_mod-fs_affs.d +UNDSYMFILES += und-affs.lst + +affs.mod: pre-affs.o mod-affs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-affs.o mod-affs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-affs.o: $(affs_mod_DEPENDENCIES) affs_mod-fs_affs.o + -rm -f $@ + $(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ affs_mod-fs_affs.o + +mod-affs.o: mod-affs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -c -o $@ $< + +mod-affs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'affs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(affs_mod_EXPORTS),no) +def-affs.lst: pre-affs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 affs/' > $@ +endif + +und-affs.lst: pre-affs.o + echo 'affs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +affs_mod-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -MD -c -o $@ $< +-include affs_mod-fs_affs.d + +CLEANFILES += cmd-affs_mod-fs_affs.lst fs-affs_mod-fs_affs.lst partmap-affs_mod-fs_affs.lst +COMMANDFILES += cmd-affs_mod-fs_affs.lst +FSFILES += fs-affs_mod-fs_affs.lst +PARTMAPFILES += partmap-affs_mod-fs_affs.lst + +cmd-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh affs > $@ || (rm -f $@; exit 1) + +fs-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh affs > $@ || (rm -f $@; exit 1) + +partmap-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh affs > $@ || (rm -f $@; exit 1) + + +affs_mod_CFLAGS = $(COMMON_CFLAGS) +affs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sfs.mod. +sfs_mod_SOURCES = fs/sfs.c +CLEANFILES += sfs.mod mod-sfs.o mod-sfs.c pre-sfs.o sfs_mod-fs_sfs.o und-sfs.lst +ifneq ($(sfs_mod_EXPORTS),no) +CLEANFILES += def-sfs.lst +DEFSYMFILES += def-sfs.lst +endif +MOSTLYCLEANFILES += sfs_mod-fs_sfs.d +UNDSYMFILES += und-sfs.lst + +sfs.mod: pre-sfs.o mod-sfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-sfs.o mod-sfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-sfs.o: $(sfs_mod_DEPENDENCIES) sfs_mod-fs_sfs.o + -rm -f $@ + $(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sfs_mod-fs_sfs.o + +mod-sfs.o: mod-sfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -c -o $@ $< + +mod-sfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'sfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(sfs_mod_EXPORTS),no) +def-sfs.lst: pre-sfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sfs/' > $@ +endif + +und-sfs.lst: pre-sfs.o + echo 'sfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +sfs_mod-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -MD -c -o $@ $< +-include sfs_mod-fs_sfs.d + +CLEANFILES += cmd-sfs_mod-fs_sfs.lst fs-sfs_mod-fs_sfs.lst partmap-sfs_mod-fs_sfs.lst +COMMANDFILES += cmd-sfs_mod-fs_sfs.lst +FSFILES += fs-sfs_mod-fs_sfs.lst +PARTMAPFILES += partmap-sfs_mod-fs_sfs.lst + +cmd-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh sfs > $@ || (rm -f $@; exit 1) + +fs-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh sfs > $@ || (rm -f $@; exit 1) + +partmap-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh sfs > $@ || (rm -f $@; exit 1) + + +sfs_mod_CFLAGS = $(COMMON_CFLAGS) +sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfsplus.mod. +hfsplus_mod_SOURCES = fs/hfsplus.c +CLEANFILES += hfsplus.mod mod-hfsplus.o mod-hfsplus.c pre-hfsplus.o hfsplus_mod-fs_hfsplus.o und-hfsplus.lst +ifneq ($(hfsplus_mod_EXPORTS),no) +CLEANFILES += def-hfsplus.lst +DEFSYMFILES += def-hfsplus.lst +endif +MOSTLYCLEANFILES += hfsplus_mod-fs_hfsplus.d +UNDSYMFILES += und-hfsplus.lst + +hfsplus.mod: pre-hfsplus.o mod-hfsplus.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hfsplus_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hfsplus.o mod-hfsplus.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hfsplus.o: $(hfsplus_mod_DEPENDENCIES) hfsplus_mod-fs_hfsplus.o + -rm -f $@ + $(TARGET_CC) $(hfsplus_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hfsplus_mod-fs_hfsplus.o + +mod-hfsplus.o: mod-hfsplus.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -c -o $@ $< + +mod-hfsplus.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hfsplus' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hfsplus_mod_EXPORTS),no) +def-hfsplus.lst: pre-hfsplus.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hfsplus/' > $@ +endif + +und-hfsplus.lst: pre-hfsplus.o + echo 'hfsplus' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hfsplus_mod-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -MD -c -o $@ $< +-include hfsplus_mod-fs_hfsplus.d + +CLEANFILES += cmd-hfsplus_mod-fs_hfsplus.lst fs-hfsplus_mod-fs_hfsplus.lst partmap-hfsplus_mod-fs_hfsplus.lst +COMMANDFILES += cmd-hfsplus_mod-fs_hfsplus.lst +FSFILES += fs-hfsplus_mod-fs_hfsplus.lst +PARTMAPFILES += partmap-hfsplus_mod-fs_hfsplus.lst + +cmd-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hfsplus > $@ || (rm -f $@; exit 1) + +fs-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hfsplus > $@ || (rm -f $@; exit 1) + +partmap-hfsplus_mod-fs_hfsplus.lst: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfsplus_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hfsplus > $@ || (rm -f $@; exit 1) + + +hfsplus_mod_CFLAGS = $(COMMON_CFLAGS) +hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reiserfs.mod. +reiserfs_mod_SOURCES = fs/reiserfs.c +CLEANFILES += reiserfs.mod mod-reiserfs.o mod-reiserfs.c pre-reiserfs.o reiserfs_mod-fs_reiserfs.o und-reiserfs.lst +ifneq ($(reiserfs_mod_EXPORTS),no) +CLEANFILES += def-reiserfs.lst +DEFSYMFILES += def-reiserfs.lst +endif +MOSTLYCLEANFILES += reiserfs_mod-fs_reiserfs.d +UNDSYMFILES += und-reiserfs.lst + +reiserfs.mod: pre-reiserfs.o mod-reiserfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reiserfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reiserfs.o mod-reiserfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reiserfs.o: $(reiserfs_mod_DEPENDENCIES) reiserfs_mod-fs_reiserfs.o + -rm -f $@ + $(TARGET_CC) $(reiserfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reiserfs_mod-fs_reiserfs.o + +mod-reiserfs.o: mod-reiserfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -c -o $@ $< + +mod-reiserfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reiserfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reiserfs_mod_EXPORTS),no) +def-reiserfs.lst: pre-reiserfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reiserfs/' > $@ +endif + +und-reiserfs.lst: pre-reiserfs.o + echo 'reiserfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reiserfs_mod-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -MD -c -o $@ $< +-include reiserfs_mod-fs_reiserfs.d + +CLEANFILES += cmd-reiserfs_mod-fs_reiserfs.lst fs-reiserfs_mod-fs_reiserfs.lst partmap-reiserfs_mod-fs_reiserfs.lst +COMMANDFILES += cmd-reiserfs_mod-fs_reiserfs.lst +FSFILES += fs-reiserfs_mod-fs_reiserfs.lst +PARTMAPFILES += partmap-reiserfs_mod-fs_reiserfs.lst + +cmd-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reiserfs > $@ || (rm -f $@; exit 1) + +fs-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reiserfs > $@ || (rm -f $@; exit 1) + +partmap-reiserfs_mod-fs_reiserfs.lst: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reiserfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reiserfs > $@ || (rm -f $@; exit 1) + + +reiserfs_mod_CFLAGS = $(COMMON_CFLAGS) +reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cpio.mod. +cpio_mod_SOURCES = fs/cpio.c +CLEANFILES += cpio.mod mod-cpio.o mod-cpio.c pre-cpio.o cpio_mod-fs_cpio.o und-cpio.lst +ifneq ($(cpio_mod_EXPORTS),no) +CLEANFILES += def-cpio.lst +DEFSYMFILES += def-cpio.lst +endif +MOSTLYCLEANFILES += cpio_mod-fs_cpio.d +UNDSYMFILES += und-cpio.lst + +cpio.mod: pre-cpio.o mod-cpio.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cpio_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cpio.o mod-cpio.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cpio.o: $(cpio_mod_DEPENDENCIES) cpio_mod-fs_cpio.o + -rm -f $@ + $(TARGET_CC) $(cpio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cpio_mod-fs_cpio.o + +mod-cpio.o: mod-cpio.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -c -o $@ $< + +mod-cpio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cpio' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cpio_mod_EXPORTS),no) +def-cpio.lst: pre-cpio.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cpio/' > $@ +endif + +und-cpio.lst: pre-cpio.o + echo 'cpio' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cpio_mod-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -MD -c -o $@ $< +-include cpio_mod-fs_cpio.d + +CLEANFILES += cmd-cpio_mod-fs_cpio.lst fs-cpio_mod-fs_cpio.lst partmap-cpio_mod-fs_cpio.lst +COMMANDFILES += cmd-cpio_mod-fs_cpio.lst +FSFILES += fs-cpio_mod-fs_cpio.lst +PARTMAPFILES += partmap-cpio_mod-fs_cpio.lst + +cmd-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cpio > $@ || (rm -f $@; exit 1) + +fs-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cpio > $@ || (rm -f $@; exit 1) + +partmap-cpio_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpio_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cpio > $@ || (rm -f $@; exit 1) + + +cpio_mod_CFLAGS = $(COMMON_CFLAGS) +cpio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For tar.mod. +tar_mod_SOURCES = fs/cpio.c +CLEANFILES += tar.mod mod-tar.o mod-tar.c pre-tar.o tar_mod-fs_cpio.o und-tar.lst +ifneq ($(tar_mod_EXPORTS),no) +CLEANFILES += def-tar.lst +DEFSYMFILES += def-tar.lst +endif +MOSTLYCLEANFILES += tar_mod-fs_cpio.d +UNDSYMFILES += und-tar.lst + +tar.mod: pre-tar.o mod-tar.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(tar_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-tar.o mod-tar.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-tar.o: $(tar_mod_DEPENDENCIES) tar_mod-fs_cpio.o + -rm -f $@ + $(TARGET_CC) $(tar_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ tar_mod-fs_cpio.o + +mod-tar.o: mod-tar.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -c -o $@ $< + +mod-tar.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'tar' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(tar_mod_EXPORTS),no) +def-tar.lst: pre-tar.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 tar/' > $@ +endif + +und-tar.lst: pre-tar.o + echo 'tar' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +tar_mod-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -MD -c -o $@ $< +-include tar_mod-fs_cpio.d + +CLEANFILES += cmd-tar_mod-fs_cpio.lst fs-tar_mod-fs_cpio.lst partmap-tar_mod-fs_cpio.lst +COMMANDFILES += cmd-tar_mod-fs_cpio.lst +FSFILES += fs-tar_mod-fs_cpio.lst +PARTMAPFILES += partmap-tar_mod-fs_cpio.lst + +cmd-tar_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh tar > $@ || (rm -f $@; exit 1) + +fs-tar_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh tar > $@ || (rm -f $@; exit 1) + +partmap-tar_mod-fs_cpio.lst: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tar_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh tar > $@ || (rm -f $@; exit 1) + + +tar_mod_CFLAGS = $(COMMON_CFLAGS) -DMODE_USTAR +tar_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For udf.mod. +udf_mod_SOURCES = fs/udf.c +CLEANFILES += udf.mod mod-udf.o mod-udf.c pre-udf.o udf_mod-fs_udf.o und-udf.lst +ifneq ($(udf_mod_EXPORTS),no) +CLEANFILES += def-udf.lst +DEFSYMFILES += def-udf.lst +endif +MOSTLYCLEANFILES += udf_mod-fs_udf.d +UNDSYMFILES += und-udf.lst + +udf.mod: pre-udf.o mod-udf.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(udf_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-udf.o mod-udf.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-udf.o: $(udf_mod_DEPENDENCIES) udf_mod-fs_udf.o + -rm -f $@ + $(TARGET_CC) $(udf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ udf_mod-fs_udf.o + +mod-udf.o: mod-udf.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -c -o $@ $< + +mod-udf.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'udf' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(udf_mod_EXPORTS),no) +def-udf.lst: pre-udf.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 udf/' > $@ +endif + +und-udf.lst: pre-udf.o + echo 'udf' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +udf_mod-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -MD -c -o $@ $< +-include udf_mod-fs_udf.d + +CLEANFILES += cmd-udf_mod-fs_udf.lst fs-udf_mod-fs_udf.lst partmap-udf_mod-fs_udf.lst +COMMANDFILES += cmd-udf_mod-fs_udf.lst +FSFILES += fs-udf_mod-fs_udf.lst +PARTMAPFILES += partmap-udf_mod-fs_udf.lst + +cmd-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh udf > $@ || (rm -f $@; exit 1) + +fs-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh udf > $@ || (rm -f $@; exit 1) + +partmap-udf_mod-fs_udf.lst: fs/udf.c $(fs/udf.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(udf_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh udf > $@ || (rm -f $@; exit 1) + + +udf_mod_CFLAGS = $(COMMON_CFLAGS) +udf_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For afs.mod. +afs_mod_SOURCES = fs/afs.c +CLEANFILES += afs.mod mod-afs.o mod-afs.c pre-afs.o afs_mod-fs_afs.o und-afs.lst +ifneq ($(afs_mod_EXPORTS),no) +CLEANFILES += def-afs.lst +DEFSYMFILES += def-afs.lst +endif +MOSTLYCLEANFILES += afs_mod-fs_afs.d +UNDSYMFILES += und-afs.lst + +afs.mod: pre-afs.o mod-afs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(afs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-afs.o mod-afs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-afs.o: $(afs_mod_DEPENDENCIES) afs_mod-fs_afs.o + -rm -f $@ + $(TARGET_CC) $(afs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ afs_mod-fs_afs.o + +mod-afs.o: mod-afs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -c -o $@ $< + +mod-afs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'afs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(afs_mod_EXPORTS),no) +def-afs.lst: pre-afs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 afs/' > $@ +endif + +und-afs.lst: pre-afs.o + echo 'afs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +afs_mod-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -MD -c -o $@ $< +-include afs_mod-fs_afs.d + +CLEANFILES += cmd-afs_mod-fs_afs.lst fs-afs_mod-fs_afs.lst partmap-afs_mod-fs_afs.lst +COMMANDFILES += cmd-afs_mod-fs_afs.lst +FSFILES += fs-afs_mod-fs_afs.lst +PARTMAPFILES += partmap-afs_mod-fs_afs.lst + +cmd-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh afs > $@ || (rm -f $@; exit 1) + +fs-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh afs > $@ || (rm -f $@; exit 1) + +partmap-afs_mod-fs_afs.lst: fs/afs.c $(fs/afs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(afs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh afs > $@ || (rm -f $@; exit 1) + + +afs_mod_CFLAGS = $(COMMON_CFLAGS) +afs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Partition maps. +pkglib_MODULES += amiga.mod apple.mod pc.mod sun.mod acorn.mod gpt.mod + +# For amiga.mod +amiga_mod_SOURCES = partmap/amiga.c +CLEANFILES += amiga.mod mod-amiga.o mod-amiga.c pre-amiga.o amiga_mod-partmap_amiga.o und-amiga.lst +ifneq ($(amiga_mod_EXPORTS),no) +CLEANFILES += def-amiga.lst +DEFSYMFILES += def-amiga.lst +endif +MOSTLYCLEANFILES += amiga_mod-partmap_amiga.d +UNDSYMFILES += und-amiga.lst + +amiga.mod: pre-amiga.o mod-amiga.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-amiga.o mod-amiga.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-amiga.o: $(amiga_mod_DEPENDENCIES) amiga_mod-partmap_amiga.o + -rm -f $@ + $(TARGET_CC) $(amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ amiga_mod-partmap_amiga.o + +mod-amiga.o: mod-amiga.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -c -o $@ $< + +mod-amiga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'amiga' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(amiga_mod_EXPORTS),no) +def-amiga.lst: pre-amiga.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 amiga/' > $@ +endif + +und-amiga.lst: pre-amiga.o + echo 'amiga' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +amiga_mod-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -MD -c -o $@ $< +-include amiga_mod-partmap_amiga.d + +CLEANFILES += cmd-amiga_mod-partmap_amiga.lst fs-amiga_mod-partmap_amiga.lst partmap-amiga_mod-partmap_amiga.lst +COMMANDFILES += cmd-amiga_mod-partmap_amiga.lst +FSFILES += fs-amiga_mod-partmap_amiga.lst +PARTMAPFILES += partmap-amiga_mod-partmap_amiga.lst + +cmd-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh amiga > $@ || (rm -f $@; exit 1) + +fs-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh amiga > $@ || (rm -f $@; exit 1) + +partmap-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh amiga > $@ || (rm -f $@; exit 1) + + +amiga_mod_CFLAGS = $(COMMON_CFLAGS) +amiga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For apple.mod +apple_mod_SOURCES = partmap/apple.c +CLEANFILES += apple.mod mod-apple.o mod-apple.c pre-apple.o apple_mod-partmap_apple.o und-apple.lst +ifneq ($(apple_mod_EXPORTS),no) +CLEANFILES += def-apple.lst +DEFSYMFILES += def-apple.lst +endif +MOSTLYCLEANFILES += apple_mod-partmap_apple.d +UNDSYMFILES += und-apple.lst + +apple.mod: pre-apple.o mod-apple.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(apple_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-apple.o mod-apple.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-apple.o: $(apple_mod_DEPENDENCIES) apple_mod-partmap_apple.o + -rm -f $@ + $(TARGET_CC) $(apple_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ apple_mod-partmap_apple.o + +mod-apple.o: mod-apple.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -c -o $@ $< + +mod-apple.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'apple' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(apple_mod_EXPORTS),no) +def-apple.lst: pre-apple.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 apple/' > $@ +endif + +und-apple.lst: pre-apple.o + echo 'apple' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +apple_mod-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -MD -c -o $@ $< +-include apple_mod-partmap_apple.d + +CLEANFILES += cmd-apple_mod-partmap_apple.lst fs-apple_mod-partmap_apple.lst partmap-apple_mod-partmap_apple.lst +COMMANDFILES += cmd-apple_mod-partmap_apple.lst +FSFILES += fs-apple_mod-partmap_apple.lst +PARTMAPFILES += partmap-apple_mod-partmap_apple.lst + +cmd-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh apple > $@ || (rm -f $@; exit 1) + +fs-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh apple > $@ || (rm -f $@; exit 1) + +partmap-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh apple > $@ || (rm -f $@; exit 1) + + +apple_mod_CFLAGS = $(COMMON_CFLAGS) +apple_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pc.mod +pc_mod_SOURCES = partmap/pc.c +CLEANFILES += pc.mod mod-pc.o mod-pc.c pre-pc.o pc_mod-partmap_pc.o und-pc.lst +ifneq ($(pc_mod_EXPORTS),no) +CLEANFILES += def-pc.lst +DEFSYMFILES += def-pc.lst +endif +MOSTLYCLEANFILES += pc_mod-partmap_pc.d +UNDSYMFILES += und-pc.lst + +pc.mod: pre-pc.o mod-pc.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pc_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pc.o mod-pc.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pc.o: $(pc_mod_DEPENDENCIES) pc_mod-partmap_pc.o + -rm -f $@ + $(TARGET_CC) $(pc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pc_mod-partmap_pc.o + +mod-pc.o: mod-pc.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -c -o $@ $< + +mod-pc.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pc' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pc_mod_EXPORTS),no) +def-pc.lst: pre-pc.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pc/' > $@ +endif + +und-pc.lst: pre-pc.o + echo 'pc' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pc_mod-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -MD -c -o $@ $< +-include pc_mod-partmap_pc.d + +CLEANFILES += cmd-pc_mod-partmap_pc.lst fs-pc_mod-partmap_pc.lst partmap-pc_mod-partmap_pc.lst +COMMANDFILES += cmd-pc_mod-partmap_pc.lst +FSFILES += fs-pc_mod-partmap_pc.lst +PARTMAPFILES += partmap-pc_mod-partmap_pc.lst + +cmd-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pc > $@ || (rm -f $@; exit 1) + +fs-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pc > $@ || (rm -f $@; exit 1) + +partmap-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pc > $@ || (rm -f $@; exit 1) + + +pc_mod_CFLAGS = $(COMMON_CFLAGS) +pc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sun.mod +sun_mod_SOURCES = partmap/sun.c +CLEANFILES += sun.mod mod-sun.o mod-sun.c pre-sun.o sun_mod-partmap_sun.o und-sun.lst +ifneq ($(sun_mod_EXPORTS),no) +CLEANFILES += def-sun.lst +DEFSYMFILES += def-sun.lst +endif +MOSTLYCLEANFILES += sun_mod-partmap_sun.d +UNDSYMFILES += und-sun.lst + +sun.mod: pre-sun.o mod-sun.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(sun_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-sun.o mod-sun.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-sun.o: $(sun_mod_DEPENDENCIES) sun_mod-partmap_sun.o + -rm -f $@ + $(TARGET_CC) $(sun_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sun_mod-partmap_sun.o + +mod-sun.o: mod-sun.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -c -o $@ $< + +mod-sun.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'sun' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(sun_mod_EXPORTS),no) +def-sun.lst: pre-sun.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sun/' > $@ +endif + +und-sun.lst: pre-sun.o + echo 'sun' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +sun_mod-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -MD -c -o $@ $< +-include sun_mod-partmap_sun.d + +CLEANFILES += cmd-sun_mod-partmap_sun.lst fs-sun_mod-partmap_sun.lst partmap-sun_mod-partmap_sun.lst +COMMANDFILES += cmd-sun_mod-partmap_sun.lst +FSFILES += fs-sun_mod-partmap_sun.lst +PARTMAPFILES += partmap-sun_mod-partmap_sun.lst + +cmd-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh sun > $@ || (rm -f $@; exit 1) + +fs-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh sun > $@ || (rm -f $@; exit 1) + +partmap-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh sun > $@ || (rm -f $@; exit 1) + + +sun_mod_CFLAGS = $(COMMON_CFLAGS) +sun_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For acorn.mod +acorn_mod_SOURCES = partmap/acorn.c +CLEANFILES += acorn.mod mod-acorn.o mod-acorn.c pre-acorn.o acorn_mod-partmap_acorn.o und-acorn.lst +ifneq ($(acorn_mod_EXPORTS),no) +CLEANFILES += def-acorn.lst +DEFSYMFILES += def-acorn.lst +endif +MOSTLYCLEANFILES += acorn_mod-partmap_acorn.d +UNDSYMFILES += und-acorn.lst + +acorn.mod: pre-acorn.o mod-acorn.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-acorn.o mod-acorn.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-acorn.o: $(acorn_mod_DEPENDENCIES) acorn_mod-partmap_acorn.o + -rm -f $@ + $(TARGET_CC) $(acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ acorn_mod-partmap_acorn.o + +mod-acorn.o: mod-acorn.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -c -o $@ $< + +mod-acorn.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'acorn' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(acorn_mod_EXPORTS),no) +def-acorn.lst: pre-acorn.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 acorn/' > $@ +endif + +und-acorn.lst: pre-acorn.o + echo 'acorn' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +acorn_mod-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -MD -c -o $@ $< +-include acorn_mod-partmap_acorn.d + +CLEANFILES += cmd-acorn_mod-partmap_acorn.lst fs-acorn_mod-partmap_acorn.lst partmap-acorn_mod-partmap_acorn.lst +COMMANDFILES += cmd-acorn_mod-partmap_acorn.lst +FSFILES += fs-acorn_mod-partmap_acorn.lst +PARTMAPFILES += partmap-acorn_mod-partmap_acorn.lst + +cmd-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh acorn > $@ || (rm -f $@; exit 1) + +fs-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh acorn > $@ || (rm -f $@; exit 1) + +partmap-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh acorn > $@ || (rm -f $@; exit 1) + + +acorn_mod_CFLAGS = $(COMMON_CFLAGS) +acorn_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gpt.mod +gpt_mod_SOURCES = partmap/gpt.c +CLEANFILES += gpt.mod mod-gpt.o mod-gpt.c pre-gpt.o gpt_mod-partmap_gpt.o und-gpt.lst +ifneq ($(gpt_mod_EXPORTS),no) +CLEANFILES += def-gpt.lst +DEFSYMFILES += def-gpt.lst +endif +MOSTLYCLEANFILES += gpt_mod-partmap_gpt.d +UNDSYMFILES += und-gpt.lst + +gpt.mod: pre-gpt.o mod-gpt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(gpt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-gpt.o mod-gpt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-gpt.o: $(gpt_mod_DEPENDENCIES) gpt_mod-partmap_gpt.o + -rm -f $@ + $(TARGET_CC) $(gpt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gpt_mod-partmap_gpt.o + +mod-gpt.o: mod-gpt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gpt_mod_CFLAGS) -c -o $@ $< + +mod-gpt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'gpt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(gpt_mod_EXPORTS),no) +def-gpt.lst: pre-gpt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gpt/' > $@ +endif + +und-gpt.lst: pre-gpt.o + echo 'gpt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +gpt_mod-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gpt_mod_CFLAGS) -MD -c -o $@ $< +-include gpt_mod-partmap_gpt.d + +CLEANFILES += cmd-gpt_mod-partmap_gpt.lst fs-gpt_mod-partmap_gpt.lst partmap-gpt_mod-partmap_gpt.lst +COMMANDFILES += cmd-gpt_mod-partmap_gpt.lst +FSFILES += fs-gpt_mod-partmap_gpt.lst +PARTMAPFILES += partmap-gpt_mod-partmap_gpt.lst + +cmd-gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gpt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh gpt > $@ || (rm -f $@; exit 1) + +fs-gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gpt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh gpt > $@ || (rm -f $@; exit 1) + +partmap-gpt_mod-partmap_gpt.lst: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gpt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh gpt > $@ || (rm -f $@; exit 1) + + +gpt_mod_CFLAGS = $(COMMON_CFLAGS) +gpt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Special disk structures and generic drivers + +pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \ + lvm.mod scsi.mod + +# For raid.mod +raid_mod_SOURCES = disk/raid.c +CLEANFILES += raid.mod mod-raid.o mod-raid.c pre-raid.o raid_mod-disk_raid.o und-raid.lst +ifneq ($(raid_mod_EXPORTS),no) +CLEANFILES += def-raid.lst +DEFSYMFILES += def-raid.lst +endif +MOSTLYCLEANFILES += raid_mod-disk_raid.d +UNDSYMFILES += und-raid.lst + +raid.mod: pre-raid.o mod-raid.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-raid.o mod-raid.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-raid.o: $(raid_mod_DEPENDENCIES) raid_mod-disk_raid.o + -rm -f $@ + $(TARGET_CC) $(raid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid_mod-disk_raid.o + +mod-raid.o: mod-raid.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -c -o $@ $< + +mod-raid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'raid' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(raid_mod_EXPORTS),no) +def-raid.lst: pre-raid.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid/' > $@ +endif + +und-raid.lst: pre-raid.o + echo 'raid' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +raid_mod-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -MD -c -o $@ $< +-include raid_mod-disk_raid.d + +CLEANFILES += cmd-raid_mod-disk_raid.lst fs-raid_mod-disk_raid.lst partmap-raid_mod-disk_raid.lst +COMMANDFILES += cmd-raid_mod-disk_raid.lst +FSFILES += fs-raid_mod-disk_raid.lst +PARTMAPFILES += partmap-raid_mod-disk_raid.lst + +cmd-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh raid > $@ || (rm -f $@; exit 1) + +fs-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh raid > $@ || (rm -f $@; exit 1) + +partmap-raid_mod-disk_raid.lst: disk/raid.c $(disk/raid.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh raid > $@ || (rm -f $@; exit 1) + + +raid_mod_CFLAGS = $(COMMON_CFLAGS) +raid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For raid5rec.mod +raid5rec_mod_SOURCES = disk/raid5_recover.c +CLEANFILES += raid5rec.mod mod-raid5rec.o mod-raid5rec.c pre-raid5rec.o raid5rec_mod-disk_raid5_recover.o und-raid5rec.lst +ifneq ($(raid5rec_mod_EXPORTS),no) +CLEANFILES += def-raid5rec.lst +DEFSYMFILES += def-raid5rec.lst +endif +MOSTLYCLEANFILES += raid5rec_mod-disk_raid5_recover.d +UNDSYMFILES += und-raid5rec.lst + +raid5rec.mod: pre-raid5rec.o mod-raid5rec.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(raid5rec_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-raid5rec.o mod-raid5rec.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-raid5rec.o: $(raid5rec_mod_DEPENDENCIES) raid5rec_mod-disk_raid5_recover.o + -rm -f $@ + $(TARGET_CC) $(raid5rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid5rec_mod-disk_raid5_recover.o + +mod-raid5rec.o: mod-raid5rec.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -c -o $@ $< + +mod-raid5rec.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'raid5rec' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(raid5rec_mod_EXPORTS),no) +def-raid5rec.lst: pre-raid5rec.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid5rec/' > $@ +endif + +und-raid5rec.lst: pre-raid5rec.o + echo 'raid5rec' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +raid5rec_mod-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -MD -c -o $@ $< +-include raid5rec_mod-disk_raid5_recover.d + +CLEANFILES += cmd-raid5rec_mod-disk_raid5_recover.lst fs-raid5rec_mod-disk_raid5_recover.lst partmap-raid5rec_mod-disk_raid5_recover.lst +COMMANDFILES += cmd-raid5rec_mod-disk_raid5_recover.lst +FSFILES += fs-raid5rec_mod-disk_raid5_recover.lst +PARTMAPFILES += partmap-raid5rec_mod-disk_raid5_recover.lst + +cmd-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh raid5rec > $@ || (rm -f $@; exit 1) + +fs-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh raid5rec > $@ || (rm -f $@; exit 1) + +partmap-raid5rec_mod-disk_raid5_recover.lst: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid5rec_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh raid5rec > $@ || (rm -f $@; exit 1) + + +raid5rec_mod_CFLAGS = $(COMMON_CFLAGS) +raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For raid6rec.mod +raid6rec_mod_SOURCES = disk/raid6_recover.c +CLEANFILES += raid6rec.mod mod-raid6rec.o mod-raid6rec.c pre-raid6rec.o raid6rec_mod-disk_raid6_recover.o und-raid6rec.lst +ifneq ($(raid6rec_mod_EXPORTS),no) +CLEANFILES += def-raid6rec.lst +DEFSYMFILES += def-raid6rec.lst +endif +MOSTLYCLEANFILES += raid6rec_mod-disk_raid6_recover.d +UNDSYMFILES += und-raid6rec.lst + +raid6rec.mod: pre-raid6rec.o mod-raid6rec.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(raid6rec_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-raid6rec.o mod-raid6rec.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-raid6rec.o: $(raid6rec_mod_DEPENDENCIES) raid6rec_mod-disk_raid6_recover.o + -rm -f $@ + $(TARGET_CC) $(raid6rec_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ raid6rec_mod-disk_raid6_recover.o + +mod-raid6rec.o: mod-raid6rec.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -c -o $@ $< + +mod-raid6rec.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'raid6rec' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(raid6rec_mod_EXPORTS),no) +def-raid6rec.lst: pre-raid6rec.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 raid6rec/' > $@ +endif + +und-raid6rec.lst: pre-raid6rec.o + echo 'raid6rec' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +raid6rec_mod-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -MD -c -o $@ $< +-include raid6rec_mod-disk_raid6_recover.d + +CLEANFILES += cmd-raid6rec_mod-disk_raid6_recover.lst fs-raid6rec_mod-disk_raid6_recover.lst partmap-raid6rec_mod-disk_raid6_recover.lst +COMMANDFILES += cmd-raid6rec_mod-disk_raid6_recover.lst +FSFILES += fs-raid6rec_mod-disk_raid6_recover.lst +PARTMAPFILES += partmap-raid6rec_mod-disk_raid6_recover.lst + +cmd-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh raid6rec > $@ || (rm -f $@; exit 1) + +fs-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh raid6rec > $@ || (rm -f $@; exit 1) + +partmap-raid6rec_mod-disk_raid6_recover.lst: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(raid6rec_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh raid6rec > $@ || (rm -f $@; exit 1) + + +raid6rec_mod_CFLAGS = $(COMMON_CFLAGS) +raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For mdraid.mod +mdraid_mod_SOURCES = disk/mdraid_linux.c +CLEANFILES += mdraid.mod mod-mdraid.o mod-mdraid.c pre-mdraid.o mdraid_mod-disk_mdraid_linux.o und-mdraid.lst +ifneq ($(mdraid_mod_EXPORTS),no) +CLEANFILES += def-mdraid.lst +DEFSYMFILES += def-mdraid.lst +endif +MOSTLYCLEANFILES += mdraid_mod-disk_mdraid_linux.d +UNDSYMFILES += und-mdraid.lst + +mdraid.mod: pre-mdraid.o mod-mdraid.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(mdraid_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-mdraid.o mod-mdraid.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-mdraid.o: $(mdraid_mod_DEPENDENCIES) mdraid_mod-disk_mdraid_linux.o + -rm -f $@ + $(TARGET_CC) $(mdraid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ mdraid_mod-disk_mdraid_linux.o + +mod-mdraid.o: mod-mdraid.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -c -o $@ $< + +mod-mdraid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'mdraid' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(mdraid_mod_EXPORTS),no) +def-mdraid.lst: pre-mdraid.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 mdraid/' > $@ +endif + +und-mdraid.lst: pre-mdraid.o + echo 'mdraid' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +mdraid_mod-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -MD -c -o $@ $< +-include mdraid_mod-disk_mdraid_linux.d + +CLEANFILES += cmd-mdraid_mod-disk_mdraid_linux.lst fs-mdraid_mod-disk_mdraid_linux.lst partmap-mdraid_mod-disk_mdraid_linux.lst +COMMANDFILES += cmd-mdraid_mod-disk_mdraid_linux.lst +FSFILES += fs-mdraid_mod-disk_mdraid_linux.lst +PARTMAPFILES += partmap-mdraid_mod-disk_mdraid_linux.lst + +cmd-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh mdraid > $@ || (rm -f $@; exit 1) + +fs-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh mdraid > $@ || (rm -f $@; exit 1) + +partmap-mdraid_mod-disk_mdraid_linux.lst: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(mdraid_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh mdraid > $@ || (rm -f $@; exit 1) + + +mdraid_mod_CFLAGS = $(COMMON_CFLAGS) +mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For dm_nv.mod +dm_nv_mod_SOURCES = disk/dmraid_nvidia.c +CLEANFILES += dm_nv.mod mod-dm_nv.o mod-dm_nv.c pre-dm_nv.o dm_nv_mod-disk_dmraid_nvidia.o und-dm_nv.lst +ifneq ($(dm_nv_mod_EXPORTS),no) +CLEANFILES += def-dm_nv.lst +DEFSYMFILES += def-dm_nv.lst +endif +MOSTLYCLEANFILES += dm_nv_mod-disk_dmraid_nvidia.d +UNDSYMFILES += und-dm_nv.lst + +dm_nv.mod: pre-dm_nv.o mod-dm_nv.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(dm_nv_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-dm_nv.o mod-dm_nv.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-dm_nv.o: $(dm_nv_mod_DEPENDENCIES) dm_nv_mod-disk_dmraid_nvidia.o + -rm -f $@ + $(TARGET_CC) $(dm_nv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ dm_nv_mod-disk_dmraid_nvidia.o + +mod-dm_nv.o: mod-dm_nv.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -c -o $@ $< + +mod-dm_nv.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'dm_nv' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(dm_nv_mod_EXPORTS),no) +def-dm_nv.lst: pre-dm_nv.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 dm_nv/' > $@ +endif + +und-dm_nv.lst: pre-dm_nv.o + echo 'dm_nv' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +dm_nv_mod-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -MD -c -o $@ $< +-include dm_nv_mod-disk_dmraid_nvidia.d + +CLEANFILES += cmd-dm_nv_mod-disk_dmraid_nvidia.lst fs-dm_nv_mod-disk_dmraid_nvidia.lst partmap-dm_nv_mod-disk_dmraid_nvidia.lst +COMMANDFILES += cmd-dm_nv_mod-disk_dmraid_nvidia.lst +FSFILES += fs-dm_nv_mod-disk_dmraid_nvidia.lst +PARTMAPFILES += partmap-dm_nv_mod-disk_dmraid_nvidia.lst + +cmd-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh dm_nv > $@ || (rm -f $@; exit 1) + +fs-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh dm_nv > $@ || (rm -f $@; exit 1) + +partmap-dm_nv_mod-disk_dmraid_nvidia.lst: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(dm_nv_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh dm_nv > $@ || (rm -f $@; exit 1) + + +dm_nv_mod_CFLAGS = $(COMMON_CFLAGS) +dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lvm.mod +lvm_mod_SOURCES = disk/lvm.c +CLEANFILES += lvm.mod mod-lvm.o mod-lvm.c pre-lvm.o lvm_mod-disk_lvm.o und-lvm.lst +ifneq ($(lvm_mod_EXPORTS),no) +CLEANFILES += def-lvm.lst +DEFSYMFILES += def-lvm.lst +endif +MOSTLYCLEANFILES += lvm_mod-disk_lvm.d +UNDSYMFILES += und-lvm.lst + +lvm.mod: pre-lvm.o mod-lvm.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lvm.o mod-lvm.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lvm.o: $(lvm_mod_DEPENDENCIES) lvm_mod-disk_lvm.o + -rm -f $@ + $(TARGET_CC) $(lvm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lvm_mod-disk_lvm.o + +mod-lvm.o: mod-lvm.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -c -o $@ $< + +mod-lvm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lvm' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lvm_mod_EXPORTS),no) +def-lvm.lst: pre-lvm.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lvm/' > $@ +endif + +und-lvm.lst: pre-lvm.o + echo 'lvm' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lvm_mod-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -MD -c -o $@ $< +-include lvm_mod-disk_lvm.d + +CLEANFILES += cmd-lvm_mod-disk_lvm.lst fs-lvm_mod-disk_lvm.lst partmap-lvm_mod-disk_lvm.lst +COMMANDFILES += cmd-lvm_mod-disk_lvm.lst +FSFILES += fs-lvm_mod-disk_lvm.lst +PARTMAPFILES += partmap-lvm_mod-disk_lvm.lst + +cmd-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lvm > $@ || (rm -f $@; exit 1) + +fs-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lvm > $@ || (rm -f $@; exit 1) + +partmap-lvm_mod-disk_lvm.lst: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lvm_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lvm > $@ || (rm -f $@; exit 1) + + +lvm_mod_CFLAGS = $(COMMON_CFLAGS) +lvm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For scsi.mod +scsi_mod_SOURCES = disk/scsi.c +CLEANFILES += scsi.mod mod-scsi.o mod-scsi.c pre-scsi.o scsi_mod-disk_scsi.o und-scsi.lst +ifneq ($(scsi_mod_EXPORTS),no) +CLEANFILES += def-scsi.lst +DEFSYMFILES += def-scsi.lst +endif +MOSTLYCLEANFILES += scsi_mod-disk_scsi.d +UNDSYMFILES += und-scsi.lst + +scsi.mod: pre-scsi.o mod-scsi.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(scsi_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-scsi.o mod-scsi.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-scsi.o: $(scsi_mod_DEPENDENCIES) scsi_mod-disk_scsi.o + -rm -f $@ + $(TARGET_CC) $(scsi_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ scsi_mod-disk_scsi.o + +mod-scsi.o: mod-scsi.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -c -o $@ $< + +mod-scsi.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'scsi' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(scsi_mod_EXPORTS),no) +def-scsi.lst: pre-scsi.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 scsi/' > $@ +endif + +und-scsi.lst: pre-scsi.o + echo 'scsi' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +scsi_mod-disk_scsi.o: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -MD -c -o $@ $< +-include scsi_mod-disk_scsi.d + +CLEANFILES += cmd-scsi_mod-disk_scsi.lst fs-scsi_mod-disk_scsi.lst partmap-scsi_mod-disk_scsi.lst +COMMANDFILES += cmd-scsi_mod-disk_scsi.lst +FSFILES += fs-scsi_mod-disk_scsi.lst +PARTMAPFILES += partmap-scsi_mod-disk_scsi.lst + +cmd-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh scsi > $@ || (rm -f $@; exit 1) + +fs-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh scsi > $@ || (rm -f $@; exit 1) + +partmap-scsi_mod-disk_scsi.lst: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(scsi_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh scsi > $@ || (rm -f $@; exit 1) + + +scsi_mod_CFLAGS = $(COMMON_CFLAGS) +scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Commands. +pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \ + cmp.mod cat.mod help.mod search.mod \ + loopback.mod fs_uuid.mod configfile.mod echo.mod \ + terminfo.mod test.mod blocklist.mod hexdump.mod \ + read.mod sleep.mod loadenv.mod crc.mod + +# For hello.mod. +hello_mod_SOURCES = hello/hello.c +CLEANFILES += hello.mod mod-hello.o mod-hello.c pre-hello.o hello_mod-hello_hello.o und-hello.lst +ifneq ($(hello_mod_EXPORTS),no) +CLEANFILES += def-hello.lst +DEFSYMFILES += def-hello.lst +endif +MOSTLYCLEANFILES += hello_mod-hello_hello.d +UNDSYMFILES += und-hello.lst + +hello.mod: pre-hello.o mod-hello.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hello.o mod-hello.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hello.o: $(hello_mod_DEPENDENCIES) hello_mod-hello_hello.o + -rm -f $@ + $(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hello_mod-hello_hello.o + +mod-hello.o: mod-hello.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -c -o $@ $< + +mod-hello.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hello' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hello_mod_EXPORTS),no) +def-hello.lst: pre-hello.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hello/' > $@ +endif + +und-hello.lst: pre-hello.o + echo 'hello' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hello_mod-hello_hello.o: hello/hello.c $(hello/hello.c_DEPENDENCIES) + $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -MD -c -o $@ $< +-include hello_mod-hello_hello.d + +CLEANFILES += cmd-hello_mod-hello_hello.lst fs-hello_mod-hello_hello.lst partmap-hello_mod-hello_hello.lst +COMMANDFILES += cmd-hello_mod-hello_hello.lst +FSFILES += fs-hello_mod-hello_hello.lst +PARTMAPFILES += partmap-hello_mod-hello_hello.lst + +cmd-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hello > $@ || (rm -f $@; exit 1) + +fs-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hello > $@ || (rm -f $@; exit 1) + +partmap-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hello > $@ || (rm -f $@; exit 1) + + +hello_mod_CFLAGS = $(COMMON_CFLAGS) +hello_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For boot.mod. +boot_mod_SOURCES = commands/boot.c +CLEANFILES += boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o und-boot.lst +ifneq ($(boot_mod_EXPORTS),no) +CLEANFILES += def-boot.lst +DEFSYMFILES += def-boot.lst +endif +MOSTLYCLEANFILES += boot_mod-commands_boot.d +UNDSYMFILES += und-boot.lst + +boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o + -rm -f $@ + $(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o + +mod-boot.o: mod-boot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $< + +mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(boot_mod_EXPORTS),no) +def-boot.lst: pre-boot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@ +endif + +und-boot.lst: pre-boot.o + echo 'boot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $< +-include boot_mod-commands_boot.d + +CLEANFILES += cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst +COMMANDFILES += cmd-boot_mod-commands_boot.lst +FSFILES += fs-boot_mod-commands_boot.lst +PARTMAPFILES += partmap-boot_mod-commands_boot.lst + +cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1) + +fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1) + +partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1) + + +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminal.mod. +terminal_mod_SOURCES = commands/terminal.c +CLEANFILES += terminal.mod mod-terminal.o mod-terminal.c pre-terminal.o terminal_mod-commands_terminal.o und-terminal.lst +ifneq ($(terminal_mod_EXPORTS),no) +CLEANFILES += def-terminal.lst +DEFSYMFILES += def-terminal.lst +endif +MOSTLYCLEANFILES += terminal_mod-commands_terminal.d +UNDSYMFILES += und-terminal.lst + +terminal.mod: pre-terminal.o mod-terminal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(terminal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-terminal.o mod-terminal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-terminal.o: $(terminal_mod_DEPENDENCIES) terminal_mod-commands_terminal.o + -rm -f $@ + $(TARGET_CC) $(terminal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ terminal_mod-commands_terminal.o + +mod-terminal.o: mod-terminal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -c -o $@ $< + +mod-terminal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'terminal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(terminal_mod_EXPORTS),no) +def-terminal.lst: pre-terminal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 terminal/' > $@ +endif + +und-terminal.lst: pre-terminal.o + echo 'terminal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +terminal_mod-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -MD -c -o $@ $< +-include terminal_mod-commands_terminal.d + +CLEANFILES += cmd-terminal_mod-commands_terminal.lst fs-terminal_mod-commands_terminal.lst partmap-terminal_mod-commands_terminal.lst +COMMANDFILES += cmd-terminal_mod-commands_terminal.lst +FSFILES += fs-terminal_mod-commands_terminal.lst +PARTMAPFILES += partmap-terminal_mod-commands_terminal.lst + +cmd-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh terminal > $@ || (rm -f $@; exit 1) + +fs-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh terminal > $@ || (rm -f $@; exit 1) + +partmap-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh terminal > $@ || (rm -f $@; exit 1) + + +terminal_mod_CFLAGS = $(COMMON_CFLAGS) +terminal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ls.mod. +ls_mod_SOURCES = commands/ls.c +CLEANFILES += ls.mod mod-ls.o mod-ls.c pre-ls.o ls_mod-commands_ls.o und-ls.lst +ifneq ($(ls_mod_EXPORTS),no) +CLEANFILES += def-ls.lst +DEFSYMFILES += def-ls.lst +endif +MOSTLYCLEANFILES += ls_mod-commands_ls.d +UNDSYMFILES += und-ls.lst + +ls.mod: pre-ls.o mod-ls.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ls.o mod-ls.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ls.o: $(ls_mod_DEPENDENCIES) ls_mod-commands_ls.o + -rm -f $@ + $(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ls_mod-commands_ls.o + +mod-ls.o: mod-ls.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -c -o $@ $< + +mod-ls.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ls' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ls_mod_EXPORTS),no) +def-ls.lst: pre-ls.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ls/' > $@ +endif + +und-ls.lst: pre-ls.o + echo 'ls' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ls_mod-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -MD -c -o $@ $< +-include ls_mod-commands_ls.d + +CLEANFILES += cmd-ls_mod-commands_ls.lst fs-ls_mod-commands_ls.lst partmap-ls_mod-commands_ls.lst +COMMANDFILES += cmd-ls_mod-commands_ls.lst +FSFILES += fs-ls_mod-commands_ls.lst +PARTMAPFILES += partmap-ls_mod-commands_ls.lst + +cmd-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ls > $@ || (rm -f $@; exit 1) + +fs-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ls > $@ || (rm -f $@; exit 1) + +partmap-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ls > $@ || (rm -f $@; exit 1) + + +ls_mod_CFLAGS = $(COMMON_CFLAGS) +ls_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cmp.mod. +cmp_mod_SOURCES = commands/cmp.c +CLEANFILES += cmp.mod mod-cmp.o mod-cmp.c pre-cmp.o cmp_mod-commands_cmp.o und-cmp.lst +ifneq ($(cmp_mod_EXPORTS),no) +CLEANFILES += def-cmp.lst +DEFSYMFILES += def-cmp.lst +endif +MOSTLYCLEANFILES += cmp_mod-commands_cmp.d +UNDSYMFILES += und-cmp.lst + +cmp.mod: pre-cmp.o mod-cmp.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cmp.o mod-cmp.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cmp.o: $(cmp_mod_DEPENDENCIES) cmp_mod-commands_cmp.o + -rm -f $@ + $(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cmp_mod-commands_cmp.o + +mod-cmp.o: mod-cmp.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -c -o $@ $< + +mod-cmp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cmp' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cmp_mod_EXPORTS),no) +def-cmp.lst: pre-cmp.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cmp/' > $@ +endif + +und-cmp.lst: pre-cmp.o + echo 'cmp' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cmp_mod-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -MD -c -o $@ $< +-include cmp_mod-commands_cmp.d + +CLEANFILES += cmd-cmp_mod-commands_cmp.lst fs-cmp_mod-commands_cmp.lst partmap-cmp_mod-commands_cmp.lst +COMMANDFILES += cmd-cmp_mod-commands_cmp.lst +FSFILES += fs-cmp_mod-commands_cmp.lst +PARTMAPFILES += partmap-cmp_mod-commands_cmp.lst + +cmd-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cmp > $@ || (rm -f $@; exit 1) + +fs-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cmp > $@ || (rm -f $@; exit 1) + +partmap-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cmp > $@ || (rm -f $@; exit 1) + + +cmp_mod_CFLAGS = $(COMMON_CFLAGS) +cmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cat.mod. +cat_mod_SOURCES = commands/cat.c +CLEANFILES += cat.mod mod-cat.o mod-cat.c pre-cat.o cat_mod-commands_cat.o und-cat.lst +ifneq ($(cat_mod_EXPORTS),no) +CLEANFILES += def-cat.lst +DEFSYMFILES += def-cat.lst +endif +MOSTLYCLEANFILES += cat_mod-commands_cat.d +UNDSYMFILES += und-cat.lst + +cat.mod: pre-cat.o mod-cat.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cat.o mod-cat.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cat.o: $(cat_mod_DEPENDENCIES) cat_mod-commands_cat.o + -rm -f $@ + $(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cat_mod-commands_cat.o + +mod-cat.o: mod-cat.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -c -o $@ $< + +mod-cat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cat' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cat_mod_EXPORTS),no) +def-cat.lst: pre-cat.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cat/' > $@ +endif + +und-cat.lst: pre-cat.o + echo 'cat' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cat_mod-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -MD -c -o $@ $< +-include cat_mod-commands_cat.d + +CLEANFILES += cmd-cat_mod-commands_cat.lst fs-cat_mod-commands_cat.lst partmap-cat_mod-commands_cat.lst +COMMANDFILES += cmd-cat_mod-commands_cat.lst +FSFILES += fs-cat_mod-commands_cat.lst +PARTMAPFILES += partmap-cat_mod-commands_cat.lst + +cmd-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cat > $@ || (rm -f $@; exit 1) + +fs-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cat > $@ || (rm -f $@; exit 1) + +partmap-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cat > $@ || (rm -f $@; exit 1) + + +cat_mod_CFLAGS = $(COMMON_CFLAGS) +cat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For echo.mod +echo_mod_SOURCES = commands/echo.c +CLEANFILES += echo.mod mod-echo.o mod-echo.c pre-echo.o echo_mod-commands_echo.o und-echo.lst +ifneq ($(echo_mod_EXPORTS),no) +CLEANFILES += def-echo.lst +DEFSYMFILES += def-echo.lst +endif +MOSTLYCLEANFILES += echo_mod-commands_echo.d +UNDSYMFILES += und-echo.lst + +echo.mod: pre-echo.o mod-echo.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-echo.o mod-echo.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-echo.o: $(echo_mod_DEPENDENCIES) echo_mod-commands_echo.o + -rm -f $@ + $(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ echo_mod-commands_echo.o + +mod-echo.o: mod-echo.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -c -o $@ $< + +mod-echo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'echo' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(echo_mod_EXPORTS),no) +def-echo.lst: pre-echo.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 echo/' > $@ +endif + +und-echo.lst: pre-echo.o + echo 'echo' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +echo_mod-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -MD -c -o $@ $< +-include echo_mod-commands_echo.d + +CLEANFILES += cmd-echo_mod-commands_echo.lst fs-echo_mod-commands_echo.lst partmap-echo_mod-commands_echo.lst +COMMANDFILES += cmd-echo_mod-commands_echo.lst +FSFILES += fs-echo_mod-commands_echo.lst +PARTMAPFILES += partmap-echo_mod-commands_echo.lst + +cmd-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh echo > $@ || (rm -f $@; exit 1) + +fs-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh echo > $@ || (rm -f $@; exit 1) + +partmap-echo_mod-commands_echo.lst: commands/echo.c $(commands/echo.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh echo > $@ || (rm -f $@; exit 1) + + +echo_mod_CFLAGS = $(COMMON_CFLAGS) +echo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For help.mod. +help_mod_SOURCES = commands/help.c +CLEANFILES += help.mod mod-help.o mod-help.c pre-help.o help_mod-commands_help.o und-help.lst +ifneq ($(help_mod_EXPORTS),no) +CLEANFILES += def-help.lst +DEFSYMFILES += def-help.lst +endif +MOSTLYCLEANFILES += help_mod-commands_help.d +UNDSYMFILES += und-help.lst + +help.mod: pre-help.o mod-help.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-help.o mod-help.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-help.o: $(help_mod_DEPENDENCIES) help_mod-commands_help.o + -rm -f $@ + $(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ help_mod-commands_help.o + +mod-help.o: mod-help.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -c -o $@ $< + +mod-help.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'help' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(help_mod_EXPORTS),no) +def-help.lst: pre-help.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 help/' > $@ +endif + +und-help.lst: pre-help.o + echo 'help' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +help_mod-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -MD -c -o $@ $< +-include help_mod-commands_help.d + +CLEANFILES += cmd-help_mod-commands_help.lst fs-help_mod-commands_help.lst partmap-help_mod-commands_help.lst +COMMANDFILES += cmd-help_mod-commands_help.lst +FSFILES += fs-help_mod-commands_help.lst +PARTMAPFILES += partmap-help_mod-commands_help.lst + +cmd-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh help > $@ || (rm -f $@; exit 1) + +fs-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh help > $@ || (rm -f $@; exit 1) + +partmap-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh help > $@ || (rm -f $@; exit 1) + + +help_mod_CFLAGS = $(COMMON_CFLAGS) +help_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For search.mod. +search_mod_SOURCES = commands/search.c +CLEANFILES += search.mod mod-search.o mod-search.c pre-search.o search_mod-commands_search.o und-search.lst +ifneq ($(search_mod_EXPORTS),no) +CLEANFILES += def-search.lst +DEFSYMFILES += def-search.lst +endif +MOSTLYCLEANFILES += search_mod-commands_search.d +UNDSYMFILES += und-search.lst + +search.mod: pre-search.o mod-search.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-search.o mod-search.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-search.o: $(search_mod_DEPENDENCIES) search_mod-commands_search.o + -rm -f $@ + $(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ search_mod-commands_search.o + +mod-search.o: mod-search.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -c -o $@ $< + +mod-search.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'search' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(search_mod_EXPORTS),no) +def-search.lst: pre-search.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 search/' > $@ +endif + +und-search.lst: pre-search.o + echo 'search' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +search_mod-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -MD -c -o $@ $< +-include search_mod-commands_search.d + +CLEANFILES += cmd-search_mod-commands_search.lst fs-search_mod-commands_search.lst partmap-search_mod-commands_search.lst +COMMANDFILES += cmd-search_mod-commands_search.lst +FSFILES += fs-search_mod-commands_search.lst +PARTMAPFILES += partmap-search_mod-commands_search.lst + +cmd-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh search > $@ || (rm -f $@; exit 1) + +fs-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh search > $@ || (rm -f $@; exit 1) + +partmap-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh search > $@ || (rm -f $@; exit 1) + + +search_mod_CFLAGS = $(COMMON_CFLAGS) +search_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For test.mod. +test_mod_SOURCES = commands/test.c +CLEANFILES += test.mod mod-test.o mod-test.c pre-test.o test_mod-commands_test.o und-test.lst +ifneq ($(test_mod_EXPORTS),no) +CLEANFILES += def-test.lst +DEFSYMFILES += def-test.lst +endif +MOSTLYCLEANFILES += test_mod-commands_test.d +UNDSYMFILES += und-test.lst + +test.mod: pre-test.o mod-test.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(test_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-test.o mod-test.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-test.o: $(test_mod_DEPENDENCIES) test_mod-commands_test.o + -rm -f $@ + $(TARGET_CC) $(test_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ test_mod-commands_test.o + +mod-test.o: mod-test.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -c -o $@ $< + +mod-test.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'test' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(test_mod_EXPORTS),no) +def-test.lst: pre-test.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 test/' > $@ +endif + +und-test.lst: pre-test.o + echo 'test' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +test_mod-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -MD -c -o $@ $< +-include test_mod-commands_test.d + +CLEANFILES += cmd-test_mod-commands_test.lst fs-test_mod-commands_test.lst partmap-test_mod-commands_test.lst +COMMANDFILES += cmd-test_mod-commands_test.lst +FSFILES += fs-test_mod-commands_test.lst +PARTMAPFILES += partmap-test_mod-commands_test.lst + +cmd-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh test > $@ || (rm -f $@; exit 1) + +fs-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh test > $@ || (rm -f $@; exit 1) + +partmap-test_mod-commands_test.lst: commands/test.c $(commands/test.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(test_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh test > $@ || (rm -f $@; exit 1) + + +test_mod_CFLAGS = $(COMMON_CFLAGS) +test_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For loopback.mod +loopback_mod_SOURCES = disk/loopback.c +CLEANFILES += loopback.mod mod-loopback.o mod-loopback.c pre-loopback.o loopback_mod-disk_loopback.o und-loopback.lst +ifneq ($(loopback_mod_EXPORTS),no) +CLEANFILES += def-loopback.lst +DEFSYMFILES += def-loopback.lst +endif +MOSTLYCLEANFILES += loopback_mod-disk_loopback.d +UNDSYMFILES += und-loopback.lst + +loopback.mod: pre-loopback.o mod-loopback.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-loopback.o mod-loopback.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-loopback.o: $(loopback_mod_DEPENDENCIES) loopback_mod-disk_loopback.o + -rm -f $@ + $(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loopback_mod-disk_loopback.o + +mod-loopback.o: mod-loopback.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -c -o $@ $< + +mod-loopback.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'loopback' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(loopback_mod_EXPORTS),no) +def-loopback.lst: pre-loopback.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loopback/' > $@ +endif + +und-loopback.lst: pre-loopback.o + echo 'loopback' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +loopback_mod-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -MD -c -o $@ $< +-include loopback_mod-disk_loopback.d + +CLEANFILES += cmd-loopback_mod-disk_loopback.lst fs-loopback_mod-disk_loopback.lst partmap-loopback_mod-disk_loopback.lst +COMMANDFILES += cmd-loopback_mod-disk_loopback.lst +FSFILES += fs-loopback_mod-disk_loopback.lst +PARTMAPFILES += partmap-loopback_mod-disk_loopback.lst + +cmd-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh loopback > $@ || (rm -f $@; exit 1) + +fs-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh loopback > $@ || (rm -f $@; exit 1) + +partmap-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh loopback > $@ || (rm -f $@; exit 1) + + +loopback_mod_CFLAGS = $(COMMON_CFLAGS) +loopback_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fs_uuid.mod +fs_uuid_mod_SOURCES = disk/fs_uuid.c +CLEANFILES += fs_uuid.mod mod-fs_uuid.o mod-fs_uuid.c pre-fs_uuid.o fs_uuid_mod-disk_fs_uuid.o und-fs_uuid.lst +ifneq ($(fs_uuid_mod_EXPORTS),no) +CLEANFILES += def-fs_uuid.lst +DEFSYMFILES += def-fs_uuid.lst +endif +MOSTLYCLEANFILES += fs_uuid_mod-disk_fs_uuid.d +UNDSYMFILES += und-fs_uuid.lst + +fs_uuid.mod: pre-fs_uuid.o mod-fs_uuid.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-fs_uuid.o mod-fs_uuid.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-fs_uuid.o: $(fs_uuid_mod_DEPENDENCIES) fs_uuid_mod-disk_fs_uuid.o + -rm -f $@ + $(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fs_uuid_mod-disk_fs_uuid.o + +mod-fs_uuid.o: mod-fs_uuid.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -c -o $@ $< + +mod-fs_uuid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fs_uuid' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(fs_uuid_mod_EXPORTS),no) +def-fs_uuid.lst: pre-fs_uuid.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fs_uuid/' > $@ +endif + +und-fs_uuid.lst: pre-fs_uuid.o + echo 'fs_uuid' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +fs_uuid_mod-disk_fs_uuid.o: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -MD -c -o $@ $< +-include fs_uuid_mod-disk_fs_uuid.d + +CLEANFILES += cmd-fs_uuid_mod-disk_fs_uuid.lst fs-fs_uuid_mod-disk_fs_uuid.lst partmap-fs_uuid_mod-disk_fs_uuid.lst +COMMANDFILES += cmd-fs_uuid_mod-disk_fs_uuid.lst +FSFILES += fs-fs_uuid_mod-disk_fs_uuid.lst +PARTMAPFILES += partmap-fs_uuid_mod-disk_fs_uuid.lst + +cmd-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh fs_uuid > $@ || (rm -f $@; exit 1) + +fs-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh fs_uuid > $@ || (rm -f $@; exit 1) + +partmap-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh fs_uuid > $@ || (rm -f $@; exit 1) + + +fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS) +fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For configfile.mod +configfile_mod_SOURCES = commands/configfile.c +CLEANFILES += configfile.mod mod-configfile.o mod-configfile.c pre-configfile.o configfile_mod-commands_configfile.o und-configfile.lst +ifneq ($(configfile_mod_EXPORTS),no) +CLEANFILES += def-configfile.lst +DEFSYMFILES += def-configfile.lst +endif +MOSTLYCLEANFILES += configfile_mod-commands_configfile.d +UNDSYMFILES += und-configfile.lst + +configfile.mod: pre-configfile.o mod-configfile.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-configfile.o mod-configfile.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-configfile.o: $(configfile_mod_DEPENDENCIES) configfile_mod-commands_configfile.o + -rm -f $@ + $(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ configfile_mod-commands_configfile.o + +mod-configfile.o: mod-configfile.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -c -o $@ $< + +mod-configfile.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'configfile' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(configfile_mod_EXPORTS),no) +def-configfile.lst: pre-configfile.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 configfile/' > $@ +endif + +und-configfile.lst: pre-configfile.o + echo 'configfile' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +configfile_mod-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -MD -c -o $@ $< +-include configfile_mod-commands_configfile.d + +CLEANFILES += cmd-configfile_mod-commands_configfile.lst fs-configfile_mod-commands_configfile.lst partmap-configfile_mod-commands_configfile.lst +COMMANDFILES += cmd-configfile_mod-commands_configfile.lst +FSFILES += fs-configfile_mod-commands_configfile.lst +PARTMAPFILES += partmap-configfile_mod-commands_configfile.lst + +cmd-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh configfile > $@ || (rm -f $@; exit 1) + +fs-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh configfile > $@ || (rm -f $@; exit 1) + +partmap-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh configfile > $@ || (rm -f $@; exit 1) + + +configfile_mod_CFLAGS = $(COMMON_CFLAGS) +configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminfo.mod. +terminfo_mod_SOURCES = term/terminfo.c term/tparm.c +CLEANFILES += terminfo.mod mod-terminfo.o mod-terminfo.c pre-terminfo.o terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o und-terminfo.lst +ifneq ($(terminfo_mod_EXPORTS),no) +CLEANFILES += def-terminfo.lst +DEFSYMFILES += def-terminfo.lst +endif +MOSTLYCLEANFILES += terminfo_mod-term_terminfo.d terminfo_mod-term_tparm.d +UNDSYMFILES += und-terminfo.lst + +terminfo.mod: pre-terminfo.o mod-terminfo.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(terminfo_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-terminfo.o mod-terminfo.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-terminfo.o: $(terminfo_mod_DEPENDENCIES) terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o + -rm -f $@ + $(TARGET_CC) $(terminfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ terminfo_mod-term_terminfo.o terminfo_mod-term_tparm.o + +mod-terminfo.o: mod-terminfo.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -c -o $@ $< + +mod-terminfo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'terminfo' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(terminfo_mod_EXPORTS),no) +def-terminfo.lst: pre-terminfo.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 terminfo/' > $@ +endif + +und-terminfo.lst: pre-terminfo.o + echo 'terminfo' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +terminfo_mod-term_terminfo.o: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) + $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -MD -c -o $@ $< +-include terminfo_mod-term_terminfo.d + +CLEANFILES += cmd-terminfo_mod-term_terminfo.lst fs-terminfo_mod-term_terminfo.lst partmap-terminfo_mod-term_terminfo.lst +COMMANDFILES += cmd-terminfo_mod-term_terminfo.lst +FSFILES += fs-terminfo_mod-term_terminfo.lst +PARTMAPFILES += partmap-terminfo_mod-term_terminfo.lst + +cmd-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh terminfo > $@ || (rm -f $@; exit 1) + +fs-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh terminfo > $@ || (rm -f $@; exit 1) + +partmap-terminfo_mod-term_terminfo.lst: term/terminfo.c $(term/terminfo.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh terminfo > $@ || (rm -f $@; exit 1) + + +terminfo_mod-term_tparm.o: term/tparm.c $(term/tparm.c_DEPENDENCIES) + $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -MD -c -o $@ $< +-include terminfo_mod-term_tparm.d + +CLEANFILES += cmd-terminfo_mod-term_tparm.lst fs-terminfo_mod-term_tparm.lst partmap-terminfo_mod-term_tparm.lst +COMMANDFILES += cmd-terminfo_mod-term_tparm.lst +FSFILES += fs-terminfo_mod-term_tparm.lst +PARTMAPFILES += partmap-terminfo_mod-term_tparm.lst + +cmd-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh terminfo > $@ || (rm -f $@; exit 1) + +fs-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh terminfo > $@ || (rm -f $@; exit 1) + +partmap-terminfo_mod-term_tparm.lst: term/tparm.c $(term/tparm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminfo_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh terminfo > $@ || (rm -f $@; exit 1) + + +terminfo_mod_CFLAGS = $(COMMON_CFLAGS) +terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For blocklist.mod. +blocklist_mod_SOURCES = commands/blocklist.c +CLEANFILES += blocklist.mod mod-blocklist.o mod-blocklist.c pre-blocklist.o blocklist_mod-commands_blocklist.o und-blocklist.lst +ifneq ($(blocklist_mod_EXPORTS),no) +CLEANFILES += def-blocklist.lst +DEFSYMFILES += def-blocklist.lst +endif +MOSTLYCLEANFILES += blocklist_mod-commands_blocklist.d +UNDSYMFILES += und-blocklist.lst + +blocklist.mod: pre-blocklist.o mod-blocklist.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(blocklist_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-blocklist.o mod-blocklist.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-blocklist.o: $(blocklist_mod_DEPENDENCIES) blocklist_mod-commands_blocklist.o + -rm -f $@ + $(TARGET_CC) $(blocklist_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ blocklist_mod-commands_blocklist.o + +mod-blocklist.o: mod-blocklist.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -c -o $@ $< + +mod-blocklist.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'blocklist' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(blocklist_mod_EXPORTS),no) +def-blocklist.lst: pre-blocklist.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 blocklist/' > $@ +endif + +und-blocklist.lst: pre-blocklist.o + echo 'blocklist' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +blocklist_mod-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -MD -c -o $@ $< +-include blocklist_mod-commands_blocklist.d + +CLEANFILES += cmd-blocklist_mod-commands_blocklist.lst fs-blocklist_mod-commands_blocklist.lst partmap-blocklist_mod-commands_blocklist.lst +COMMANDFILES += cmd-blocklist_mod-commands_blocklist.lst +FSFILES += fs-blocklist_mod-commands_blocklist.lst +PARTMAPFILES += partmap-blocklist_mod-commands_blocklist.lst + +cmd-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh blocklist > $@ || (rm -f $@; exit 1) + +fs-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh blocklist > $@ || (rm -f $@; exit 1) + +partmap-blocklist_mod-commands_blocklist.lst: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(blocklist_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh blocklist > $@ || (rm -f $@; exit 1) + + +blocklist_mod_CFLAGS = $(COMMON_CFLAGS) +blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hexdump.mod. +hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c +CLEANFILES += hexdump.mod mod-hexdump.o mod-hexdump.c pre-hexdump.o hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o und-hexdump.lst +ifneq ($(hexdump_mod_EXPORTS),no) +CLEANFILES += def-hexdump.lst +DEFSYMFILES += def-hexdump.lst +endif +MOSTLYCLEANFILES += hexdump_mod-commands_hexdump.d hexdump_mod-lib_hexdump.d +UNDSYMFILES += und-hexdump.lst + +hexdump.mod: pre-hexdump.o mod-hexdump.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hexdump_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hexdump.o mod-hexdump.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hexdump.o: $(hexdump_mod_DEPENDENCIES) hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o + -rm -f $@ + $(TARGET_CC) $(hexdump_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hexdump_mod-commands_hexdump.o hexdump_mod-lib_hexdump.o + +mod-hexdump.o: mod-hexdump.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -c -o $@ $< + +mod-hexdump.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hexdump' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hexdump_mod_EXPORTS),no) +def-hexdump.lst: pre-hexdump.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hexdump/' > $@ +endif + +und-hexdump.lst: pre-hexdump.o + echo 'hexdump' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hexdump_mod-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -MD -c -o $@ $< +-include hexdump_mod-commands_hexdump.d + +CLEANFILES += cmd-hexdump_mod-commands_hexdump.lst fs-hexdump_mod-commands_hexdump.lst partmap-hexdump_mod-commands_hexdump.lst +COMMANDFILES += cmd-hexdump_mod-commands_hexdump.lst +FSFILES += fs-hexdump_mod-commands_hexdump.lst +PARTMAPFILES += partmap-hexdump_mod-commands_hexdump.lst + +cmd-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hexdump > $@ || (rm -f $@; exit 1) + +fs-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hexdump > $@ || (rm -f $@; exit 1) + +partmap-hexdump_mod-commands_hexdump.lst: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hexdump > $@ || (rm -f $@; exit 1) + + +hexdump_mod-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -MD -c -o $@ $< +-include hexdump_mod-lib_hexdump.d + +CLEANFILES += cmd-hexdump_mod-lib_hexdump.lst fs-hexdump_mod-lib_hexdump.lst partmap-hexdump_mod-lib_hexdump.lst +COMMANDFILES += cmd-hexdump_mod-lib_hexdump.lst +FSFILES += fs-hexdump_mod-lib_hexdump.lst +PARTMAPFILES += partmap-hexdump_mod-lib_hexdump.lst + +cmd-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hexdump > $@ || (rm -f $@; exit 1) + +fs-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hexdump > $@ || (rm -f $@; exit 1) + +partmap-hexdump_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hexdump_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hexdump > $@ || (rm -f $@; exit 1) + + +hexdump_mod_CFLAGS = $(COMMON_CFLAGS) +hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For read.mod. +read_mod_SOURCES = commands/read.c +CLEANFILES += read.mod mod-read.o mod-read.c pre-read.o read_mod-commands_read.o und-read.lst +ifneq ($(read_mod_EXPORTS),no) +CLEANFILES += def-read.lst +DEFSYMFILES += def-read.lst +endif +MOSTLYCLEANFILES += read_mod-commands_read.d +UNDSYMFILES += und-read.lst + +read.mod: pre-read.o mod-read.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(read_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-read.o mod-read.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-read.o: $(read_mod_DEPENDENCIES) read_mod-commands_read.o + -rm -f $@ + $(TARGET_CC) $(read_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ read_mod-commands_read.o + +mod-read.o: mod-read.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -c -o $@ $< + +mod-read.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'read' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(read_mod_EXPORTS),no) +def-read.lst: pre-read.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 read/' > $@ +endif + +und-read.lst: pre-read.o + echo 'read' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +read_mod-commands_read.o: commands/read.c $(commands/read.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -MD -c -o $@ $< +-include read_mod-commands_read.d + +CLEANFILES += cmd-read_mod-commands_read.lst fs-read_mod-commands_read.lst partmap-read_mod-commands_read.lst +COMMANDFILES += cmd-read_mod-commands_read.lst +FSFILES += fs-read_mod-commands_read.lst +PARTMAPFILES += partmap-read_mod-commands_read.lst + +cmd-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh read > $@ || (rm -f $@; exit 1) + +fs-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh read > $@ || (rm -f $@; exit 1) + +partmap-read_mod-commands_read.lst: commands/read.c $(commands/read.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(read_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh read > $@ || (rm -f $@; exit 1) + + +read_mod_CFLAGS = $(COMMON_CFLAGS) +read_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sleep.mod. +sleep_mod_SOURCES = commands/sleep.c +CLEANFILES += sleep.mod mod-sleep.o mod-sleep.c pre-sleep.o sleep_mod-commands_sleep.o und-sleep.lst +ifneq ($(sleep_mod_EXPORTS),no) +CLEANFILES += def-sleep.lst +DEFSYMFILES += def-sleep.lst +endif +MOSTLYCLEANFILES += sleep_mod-commands_sleep.d +UNDSYMFILES += und-sleep.lst + +sleep.mod: pre-sleep.o mod-sleep.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(sleep_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-sleep.o mod-sleep.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-sleep.o: $(sleep_mod_DEPENDENCIES) sleep_mod-commands_sleep.o + -rm -f $@ + $(TARGET_CC) $(sleep_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sleep_mod-commands_sleep.o + +mod-sleep.o: mod-sleep.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -c -o $@ $< + +mod-sleep.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'sleep' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(sleep_mod_EXPORTS),no) +def-sleep.lst: pre-sleep.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sleep/' > $@ +endif + +und-sleep.lst: pre-sleep.o + echo 'sleep' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +sleep_mod-commands_sleep.o: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -MD -c -o $@ $< +-include sleep_mod-commands_sleep.d + +CLEANFILES += cmd-sleep_mod-commands_sleep.lst fs-sleep_mod-commands_sleep.lst partmap-sleep_mod-commands_sleep.lst +COMMANDFILES += cmd-sleep_mod-commands_sleep.lst +FSFILES += fs-sleep_mod-commands_sleep.lst +PARTMAPFILES += partmap-sleep_mod-commands_sleep.lst + +cmd-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh sleep > $@ || (rm -f $@; exit 1) + +fs-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh sleep > $@ || (rm -f $@; exit 1) + +partmap-sleep_mod-commands_sleep.lst: commands/sleep.c $(commands/sleep.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sleep_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh sleep > $@ || (rm -f $@; exit 1) + + +sleep_mod_CFLAGS = $(COMMON_CFLAGS) +sleep_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For loadenv.mod. +loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c +CLEANFILES += loadenv.mod mod-loadenv.o mod-loadenv.c pre-loadenv.o loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o und-loadenv.lst +ifneq ($(loadenv_mod_EXPORTS),no) +CLEANFILES += def-loadenv.lst +DEFSYMFILES += def-loadenv.lst +endif +MOSTLYCLEANFILES += loadenv_mod-commands_loadenv.d loadenv_mod-lib_envblk.d +UNDSYMFILES += und-loadenv.lst + +loadenv.mod: pre-loadenv.o mod-loadenv.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(loadenv_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-loadenv.o mod-loadenv.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-loadenv.o: $(loadenv_mod_DEPENDENCIES) loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o + -rm -f $@ + $(TARGET_CC) $(loadenv_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loadenv_mod-commands_loadenv.o loadenv_mod-lib_envblk.o + +mod-loadenv.o: mod-loadenv.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -c -o $@ $< + +mod-loadenv.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'loadenv' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(loadenv_mod_EXPORTS),no) +def-loadenv.lst: pre-loadenv.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loadenv/' > $@ +endif + +und-loadenv.lst: pre-loadenv.o + echo 'loadenv' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +loadenv_mod-commands_loadenv.o: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -MD -c -o $@ $< +-include loadenv_mod-commands_loadenv.d + +CLEANFILES += cmd-loadenv_mod-commands_loadenv.lst fs-loadenv_mod-commands_loadenv.lst partmap-loadenv_mod-commands_loadenv.lst +COMMANDFILES += cmd-loadenv_mod-commands_loadenv.lst +FSFILES += fs-loadenv_mod-commands_loadenv.lst +PARTMAPFILES += partmap-loadenv_mod-commands_loadenv.lst + +cmd-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh loadenv > $@ || (rm -f $@; exit 1) + +fs-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh loadenv > $@ || (rm -f $@; exit 1) + +partmap-loadenv_mod-commands_loadenv.lst: commands/loadenv.c $(commands/loadenv.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh loadenv > $@ || (rm -f $@; exit 1) + + +loadenv_mod-lib_envblk.o: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -MD -c -o $@ $< +-include loadenv_mod-lib_envblk.d + +CLEANFILES += cmd-loadenv_mod-lib_envblk.lst fs-loadenv_mod-lib_envblk.lst partmap-loadenv_mod-lib_envblk.lst +COMMANDFILES += cmd-loadenv_mod-lib_envblk.lst +FSFILES += fs-loadenv_mod-lib_envblk.lst +PARTMAPFILES += partmap-loadenv_mod-lib_envblk.lst + +cmd-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh loadenv > $@ || (rm -f $@; exit 1) + +fs-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh loadenv > $@ || (rm -f $@; exit 1) + +partmap-loadenv_mod-lib_envblk.lst: lib/envblk.c $(lib/envblk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loadenv_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh loadenv > $@ || (rm -f $@; exit 1) + + +loadenv_mod_CFLAGS = $(COMMON_CFLAGS) +loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For crc.mod. +crc_mod_SOURCES = commands/crc.c lib/crc.c +CLEANFILES += crc.mod mod-crc.o mod-crc.c pre-crc.o crc_mod-commands_crc.o crc_mod-lib_crc.o und-crc.lst +ifneq ($(crc_mod_EXPORTS),no) +CLEANFILES += def-crc.lst +DEFSYMFILES += def-crc.lst +endif +MOSTLYCLEANFILES += crc_mod-commands_crc.d crc_mod-lib_crc.d +UNDSYMFILES += und-crc.lst + +crc.mod: pre-crc.o mod-crc.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(crc_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-crc.o mod-crc.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-crc.o: $(crc_mod_DEPENDENCIES) crc_mod-commands_crc.o crc_mod-lib_crc.o + -rm -f $@ + $(TARGET_CC) $(crc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ crc_mod-commands_crc.o crc_mod-lib_crc.o + +mod-crc.o: mod-crc.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -c -o $@ $< + +mod-crc.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'crc' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(crc_mod_EXPORTS),no) +def-crc.lst: pre-crc.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 crc/' > $@ +endif + +und-crc.lst: pre-crc.o + echo 'crc' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +crc_mod-commands_crc.o: commands/crc.c $(commands/crc.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -MD -c -o $@ $< +-include crc_mod-commands_crc.d + +CLEANFILES += cmd-crc_mod-commands_crc.lst fs-crc_mod-commands_crc.lst partmap-crc_mod-commands_crc.lst +COMMANDFILES += cmd-crc_mod-commands_crc.lst +FSFILES += fs-crc_mod-commands_crc.lst +PARTMAPFILES += partmap-crc_mod-commands_crc.lst + +cmd-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh crc > $@ || (rm -f $@; exit 1) + +fs-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh crc > $@ || (rm -f $@; exit 1) + +partmap-crc_mod-commands_crc.lst: commands/crc.c $(commands/crc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh crc > $@ || (rm -f $@; exit 1) + + +crc_mod-lib_crc.o: lib/crc.c $(lib/crc.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -MD -c -o $@ $< +-include crc_mod-lib_crc.d + +CLEANFILES += cmd-crc_mod-lib_crc.lst fs-crc_mod-lib_crc.lst partmap-crc_mod-lib_crc.lst +COMMANDFILES += cmd-crc_mod-lib_crc.lst +FSFILES += fs-crc_mod-lib_crc.lst +PARTMAPFILES += partmap-crc_mod-lib_crc.lst + +cmd-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh crc > $@ || (rm -f $@; exit 1) + +fs-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh crc > $@ || (rm -f $@; exit 1) + +partmap-crc_mod-lib_crc.lst: lib/crc.c $(lib/crc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(crc_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh crc > $@ || (rm -f $@; exit 1) + + +crc_mod_CFLAGS = $(COMMON_CFLAGS) +crc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Common Video Subsystem specific modules. +pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \ + png.mod font.mod gfxterm.mod + +# For video.mod. +video_mod_SOURCES = video/video.c +CLEANFILES += video.mod mod-video.o mod-video.c pre-video.o video_mod-video_video.o und-video.lst +ifneq ($(video_mod_EXPORTS),no) +CLEANFILES += def-video.lst +DEFSYMFILES += def-video.lst +endif +MOSTLYCLEANFILES += video_mod-video_video.d +UNDSYMFILES += und-video.lst + +video.mod: pre-video.o mod-video.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(video_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-video.o mod-video.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-video.o: $(video_mod_DEPENDENCIES) video_mod-video_video.o + -rm -f $@ + $(TARGET_CC) $(video_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ video_mod-video_video.o + +mod-video.o: mod-video.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -c -o $@ $< + +mod-video.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'video' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(video_mod_EXPORTS),no) +def-video.lst: pre-video.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 video/' > $@ +endif + +und-video.lst: pre-video.o + echo 'video' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +video_mod-video_video.o: video/video.c $(video/video.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -MD -c -o $@ $< +-include video_mod-video_video.d + +CLEANFILES += cmd-video_mod-video_video.lst fs-video_mod-video_video.lst partmap-video_mod-video_video.lst +COMMANDFILES += cmd-video_mod-video_video.lst +FSFILES += fs-video_mod-video_video.lst +PARTMAPFILES += partmap-video_mod-video_video.lst + +cmd-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh video > $@ || (rm -f $@; exit 1) + +fs-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh video > $@ || (rm -f $@; exit 1) + +partmap-video_mod-video_video.lst: video/video.c $(video/video.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(video_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh video > $@ || (rm -f $@; exit 1) + + +video_mod_CFLAGS = $(COMMON_CFLAGS) +video_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For videotest.mod. +videotest_mod_SOURCES = commands/videotest.c +CLEANFILES += videotest.mod mod-videotest.o mod-videotest.c pre-videotest.o videotest_mod-commands_videotest.o und-videotest.lst +ifneq ($(videotest_mod_EXPORTS),no) +CLEANFILES += def-videotest.lst +DEFSYMFILES += def-videotest.lst +endif +MOSTLYCLEANFILES += videotest_mod-commands_videotest.d +UNDSYMFILES += und-videotest.lst + +videotest.mod: pre-videotest.o mod-videotest.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(videotest_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-videotest.o mod-videotest.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-videotest.o: $(videotest_mod_DEPENDENCIES) videotest_mod-commands_videotest.o + -rm -f $@ + $(TARGET_CC) $(videotest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ videotest_mod-commands_videotest.o + +mod-videotest.o: mod-videotest.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -c -o $@ $< + +mod-videotest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'videotest' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(videotest_mod_EXPORTS),no) +def-videotest.lst: pre-videotest.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 videotest/' > $@ +endif + +und-videotest.lst: pre-videotest.o + echo 'videotest' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +videotest_mod-commands_videotest.o: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -MD -c -o $@ $< +-include videotest_mod-commands_videotest.d + +CLEANFILES += cmd-videotest_mod-commands_videotest.lst fs-videotest_mod-commands_videotest.lst partmap-videotest_mod-commands_videotest.lst +COMMANDFILES += cmd-videotest_mod-commands_videotest.lst +FSFILES += fs-videotest_mod-commands_videotest.lst +PARTMAPFILES += partmap-videotest_mod-commands_videotest.lst + +cmd-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh videotest > $@ || (rm -f $@; exit 1) + +fs-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh videotest > $@ || (rm -f $@; exit 1) + +partmap-videotest_mod-commands_videotest.lst: commands/videotest.c $(commands/videotest.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(videotest_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh videotest > $@ || (rm -f $@; exit 1) + + +videotest_mod_CFLAGS = $(COMMON_CFLAGS) +videotest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bitmap.mod +bitmap_mod_SOURCES = video/bitmap.c +CLEANFILES += bitmap.mod mod-bitmap.o mod-bitmap.c pre-bitmap.o bitmap_mod-video_bitmap.o und-bitmap.lst +ifneq ($(bitmap_mod_EXPORTS),no) +CLEANFILES += def-bitmap.lst +DEFSYMFILES += def-bitmap.lst +endif +MOSTLYCLEANFILES += bitmap_mod-video_bitmap.d +UNDSYMFILES += und-bitmap.lst + +bitmap.mod: pre-bitmap.o mod-bitmap.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-bitmap.o mod-bitmap.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-bitmap.o: $(bitmap_mod_DEPENDENCIES) bitmap_mod-video_bitmap.o + -rm -f $@ + $(TARGET_CC) $(bitmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bitmap_mod-video_bitmap.o + +mod-bitmap.o: mod-bitmap.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -c -o $@ $< + +mod-bitmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'bitmap' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(bitmap_mod_EXPORTS),no) +def-bitmap.lst: pre-bitmap.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bitmap/' > $@ +endif + +und-bitmap.lst: pre-bitmap.o + echo 'bitmap' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +bitmap_mod-video_bitmap.o: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -MD -c -o $@ $< +-include bitmap_mod-video_bitmap.d + +CLEANFILES += cmd-bitmap_mod-video_bitmap.lst fs-bitmap_mod-video_bitmap.lst partmap-bitmap_mod-video_bitmap.lst +COMMANDFILES += cmd-bitmap_mod-video_bitmap.lst +FSFILES += fs-bitmap_mod-video_bitmap.lst +PARTMAPFILES += partmap-bitmap_mod-video_bitmap.lst + +cmd-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh bitmap > $@ || (rm -f $@; exit 1) + +fs-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh bitmap > $@ || (rm -f $@; exit 1) + +partmap-bitmap_mod-video_bitmap.lst: video/bitmap.c $(video/bitmap.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo -I$(srcdir)/video $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bitmap_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh bitmap > $@ || (rm -f $@; exit 1) + + +bitmap_mod_CFLAGS = $(COMMON_CFLAGS) +bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For tga.mod +tga_mod_SOURCES = video/readers/tga.c +CLEANFILES += tga.mod mod-tga.o mod-tga.c pre-tga.o tga_mod-video_readers_tga.o und-tga.lst +ifneq ($(tga_mod_EXPORTS),no) +CLEANFILES += def-tga.lst +DEFSYMFILES += def-tga.lst +endif +MOSTLYCLEANFILES += tga_mod-video_readers_tga.d +UNDSYMFILES += und-tga.lst + +tga.mod: pre-tga.o mod-tga.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-tga.o mod-tga.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-tga.o: $(tga_mod_DEPENDENCIES) tga_mod-video_readers_tga.o + -rm -f $@ + $(TARGET_CC) $(tga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ tga_mod-video_readers_tga.o + +mod-tga.o: mod-tga.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -c -o $@ $< + +mod-tga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'tga' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(tga_mod_EXPORTS),no) +def-tga.lst: pre-tga.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 tga/' > $@ +endif + +und-tga.lst: pre-tga.o + echo 'tga' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +tga_mod-video_readers_tga.o: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -MD -c -o $@ $< +-include tga_mod-video_readers_tga.d + +CLEANFILES += cmd-tga_mod-video_readers_tga.lst fs-tga_mod-video_readers_tga.lst partmap-tga_mod-video_readers_tga.lst +COMMANDFILES += cmd-tga_mod-video_readers_tga.lst +FSFILES += fs-tga_mod-video_readers_tga.lst +PARTMAPFILES += partmap-tga_mod-video_readers_tga.lst + +cmd-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh tga > $@ || (rm -f $@; exit 1) + +fs-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh tga > $@ || (rm -f $@; exit 1) + +partmap-tga_mod-video_readers_tga.lst: video/readers/tga.c $(video/readers/tga.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(tga_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh tga > $@ || (rm -f $@; exit 1) + + +tga_mod_CFLAGS = $(COMMON_CFLAGS) +tga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jpeg.mod. +jpeg_mod_SOURCES = video/readers/jpeg.c +CLEANFILES += jpeg.mod mod-jpeg.o mod-jpeg.c pre-jpeg.o jpeg_mod-video_readers_jpeg.o und-jpeg.lst +ifneq ($(jpeg_mod_EXPORTS),no) +CLEANFILES += def-jpeg.lst +DEFSYMFILES += def-jpeg.lst +endif +MOSTLYCLEANFILES += jpeg_mod-video_readers_jpeg.d +UNDSYMFILES += und-jpeg.lst + +jpeg.mod: pre-jpeg.o mod-jpeg.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(jpeg_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-jpeg.o mod-jpeg.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-jpeg.o: $(jpeg_mod_DEPENDENCIES) jpeg_mod-video_readers_jpeg.o + -rm -f $@ + $(TARGET_CC) $(jpeg_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ jpeg_mod-video_readers_jpeg.o + +mod-jpeg.o: mod-jpeg.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -c -o $@ $< + +mod-jpeg.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'jpeg' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(jpeg_mod_EXPORTS),no) +def-jpeg.lst: pre-jpeg.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jpeg/' > $@ +endif + +und-jpeg.lst: pre-jpeg.o + echo 'jpeg' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +jpeg_mod-video_readers_jpeg.o: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -MD -c -o $@ $< +-include jpeg_mod-video_readers_jpeg.d + +CLEANFILES += cmd-jpeg_mod-video_readers_jpeg.lst fs-jpeg_mod-video_readers_jpeg.lst partmap-jpeg_mod-video_readers_jpeg.lst +COMMANDFILES += cmd-jpeg_mod-video_readers_jpeg.lst +FSFILES += fs-jpeg_mod-video_readers_jpeg.lst +PARTMAPFILES += partmap-jpeg_mod-video_readers_jpeg.lst + +cmd-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh jpeg > $@ || (rm -f $@; exit 1) + +fs-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh jpeg > $@ || (rm -f $@; exit 1) + +partmap-jpeg_mod-video_readers_jpeg.lst: video/readers/jpeg.c $(video/readers/jpeg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jpeg_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh jpeg > $@ || (rm -f $@; exit 1) + + +jpeg_mod_CFLAGS = $(COMMON_CFLAGS) +jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For png.mod. +png_mod_SOURCES = video/readers/png.c +CLEANFILES += png.mod mod-png.o mod-png.c pre-png.o png_mod-video_readers_png.o und-png.lst +ifneq ($(png_mod_EXPORTS),no) +CLEANFILES += def-png.lst +DEFSYMFILES += def-png.lst +endif +MOSTLYCLEANFILES += png_mod-video_readers_png.d +UNDSYMFILES += und-png.lst + +png.mod: pre-png.o mod-png.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(png_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-png.o mod-png.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-png.o: $(png_mod_DEPENDENCIES) png_mod-video_readers_png.o + -rm -f $@ + $(TARGET_CC) $(png_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ png_mod-video_readers_png.o + +mod-png.o: mod-png.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -c -o $@ $< + +mod-png.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'png' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(png_mod_EXPORTS),no) +def-png.lst: pre-png.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 png/' > $@ +endif + +und-png.lst: pre-png.o + echo 'png' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +png_mod-video_readers_png.o: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -MD -c -o $@ $< +-include png_mod-video_readers_png.d + +CLEANFILES += cmd-png_mod-video_readers_png.lst fs-png_mod-video_readers_png.lst partmap-png_mod-video_readers_png.lst +COMMANDFILES += cmd-png_mod-video_readers_png.lst +FSFILES += fs-png_mod-video_readers_png.lst +PARTMAPFILES += partmap-png_mod-video_readers_png.lst + +cmd-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh png > $@ || (rm -f $@; exit 1) + +fs-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh png > $@ || (rm -f $@; exit 1) + +partmap-png_mod-video_readers_png.lst: video/readers/png.c $(video/readers/png.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/readers -I$(srcdir)/video/readers $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(png_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh png > $@ || (rm -f $@; exit 1) + + +png_mod_CFLAGS = $(COMMON_CFLAGS) +png_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For font.mod. +font_mod_SOURCES = font/font_cmd.c font/font.c +CLEANFILES += font.mod mod-font.o mod-font.c pre-font.o font_mod-font_font_cmd.o font_mod-font_font.o und-font.lst +ifneq ($(font_mod_EXPORTS),no) +CLEANFILES += def-font.lst +DEFSYMFILES += def-font.lst +endif +MOSTLYCLEANFILES += font_mod-font_font_cmd.d font_mod-font_font.d +UNDSYMFILES += und-font.lst + +font.mod: pre-font.o mod-font.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-font.o mod-font.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-font.o: $(font_mod_DEPENDENCIES) font_mod-font_font_cmd.o font_mod-font_font.o + -rm -f $@ + $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ font_mod-font_font_cmd.o font_mod-font_font.o + +mod-font.o: mod-font.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -c -o $@ $< + +mod-font.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'font' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(font_mod_EXPORTS),no) +def-font.lst: pre-font.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 font/' > $@ +endif + +und-font.lst: pre-font.o + echo 'font' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +font_mod-font_font_cmd.o: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) + $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $< +-include font_mod-font_font_cmd.d + +CLEANFILES += cmd-font_mod-font_font_cmd.lst fs-font_mod-font_font_cmd.lst partmap-font_mod-font_font_cmd.lst +COMMANDFILES += cmd-font_mod-font_font_cmd.lst +FSFILES += fs-font_mod-font_font_cmd.lst +PARTMAPFILES += partmap-font_mod-font_font_cmd.lst + +cmd-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1) + +fs-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1) + +partmap-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1) + + +font_mod-font_font.o: font/font.c $(font/font.c_DEPENDENCIES) + $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $< +-include font_mod-font_font.d + +CLEANFILES += cmd-font_mod-font_font.lst fs-font_mod-font_font.lst partmap-font_mod-font_font.lst +COMMANDFILES += cmd-font_mod-font_font.lst +FSFILES += fs-font_mod-font_font.lst +PARTMAPFILES += partmap-font_mod-font_font.lst + +cmd-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1) + +fs-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1) + +partmap-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1) + + +font_mod_CFLAGS = $(COMMON_CFLAGS) +font_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gfxterm.mod. +gfxterm_mod_SOURCES = term/gfxterm.c +CLEANFILES += gfxterm.mod mod-gfxterm.o mod-gfxterm.c pre-gfxterm.o gfxterm_mod-term_gfxterm.o und-gfxterm.lst +ifneq ($(gfxterm_mod_EXPORTS),no) +CLEANFILES += def-gfxterm.lst +DEFSYMFILES += def-gfxterm.lst +endif +MOSTLYCLEANFILES += gfxterm_mod-term_gfxterm.d +UNDSYMFILES += und-gfxterm.lst + +gfxterm.mod: pre-gfxterm.o mod-gfxterm.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(gfxterm_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-gfxterm.o mod-gfxterm.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-gfxterm.o: $(gfxterm_mod_DEPENDENCIES) gfxterm_mod-term_gfxterm.o + -rm -f $@ + $(TARGET_CC) $(gfxterm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gfxterm_mod-term_gfxterm.o + +mod-gfxterm.o: mod-gfxterm.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -c -o $@ $< + +mod-gfxterm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'gfxterm' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(gfxterm_mod_EXPORTS),no) +def-gfxterm.lst: pre-gfxterm.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gfxterm/' > $@ +endif + +und-gfxterm.lst: pre-gfxterm.o + echo 'gfxterm' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +gfxterm_mod-term_gfxterm.o: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) + $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -MD -c -o $@ $< +-include gfxterm_mod-term_gfxterm.d + +CLEANFILES += cmd-gfxterm_mod-term_gfxterm.lst fs-gfxterm_mod-term_gfxterm.lst partmap-gfxterm_mod-term_gfxterm.lst +COMMANDFILES += cmd-gfxterm_mod-term_gfxterm.lst +FSFILES += fs-gfxterm_mod-term_gfxterm.lst +PARTMAPFILES += partmap-gfxterm_mod-term_gfxterm.lst + +cmd-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh gfxterm > $@ || (rm -f $@; exit 1) + +fs-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh gfxterm > $@ || (rm -f $@; exit 1) + +partmap-gfxterm_mod-term_gfxterm.lst: term/gfxterm.c $(term/gfxterm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gfxterm_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh gfxterm > $@ || (rm -f $@; exit 1) + + +gfxterm_mod_CFLAGS = $(COMMON_CFLAGS) +gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Misc. +pkglib_MODULES += gzio.mod bufio.mod elf.mod + +# For elf.mod. +elf_mod_SOURCES = kern/elf.c +CLEANFILES += elf.mod mod-elf.o mod-elf.c pre-elf.o elf_mod-kern_elf.o und-elf.lst +ifneq ($(elf_mod_EXPORTS),no) +CLEANFILES += def-elf.lst +DEFSYMFILES += def-elf.lst +endif +MOSTLYCLEANFILES += elf_mod-kern_elf.d +UNDSYMFILES += und-elf.lst + +elf.mod: pre-elf.o mod-elf.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(elf_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-elf.o mod-elf.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-elf.o: $(elf_mod_DEPENDENCIES) elf_mod-kern_elf.o + -rm -f $@ + $(TARGET_CC) $(elf_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ elf_mod-kern_elf.o + +mod-elf.o: mod-elf.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -c -o $@ $< + +mod-elf.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'elf' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(elf_mod_EXPORTS),no) +def-elf.lst: pre-elf.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 elf/' > $@ +endif + +und-elf.lst: pre-elf.o + echo 'elf' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +elf_mod-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -MD -c -o $@ $< +-include elf_mod-kern_elf.d + +CLEANFILES += cmd-elf_mod-kern_elf.lst fs-elf_mod-kern_elf.lst partmap-elf_mod-kern_elf.lst +COMMANDFILES += cmd-elf_mod-kern_elf.lst +FSFILES += fs-elf_mod-kern_elf.lst +PARTMAPFILES += partmap-elf_mod-kern_elf.lst + +cmd-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh elf > $@ || (rm -f $@; exit 1) + +fs-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh elf > $@ || (rm -f $@; exit 1) + +partmap-elf_mod-kern_elf.lst: kern/elf.c $(kern/elf.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(elf_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh elf > $@ || (rm -f $@; exit 1) + + +elf_mod_CFLAGS = $(COMMON_CFLAGS) +elf_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gzio.mod. +gzio_mod_SOURCES = io/gzio.c +CLEANFILES += gzio.mod mod-gzio.o mod-gzio.c pre-gzio.o gzio_mod-io_gzio.o und-gzio.lst +ifneq ($(gzio_mod_EXPORTS),no) +CLEANFILES += def-gzio.lst +DEFSYMFILES += def-gzio.lst +endif +MOSTLYCLEANFILES += gzio_mod-io_gzio.d +UNDSYMFILES += und-gzio.lst + +gzio.mod: pre-gzio.o mod-gzio.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-gzio.o mod-gzio.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-gzio.o: $(gzio_mod_DEPENDENCIES) gzio_mod-io_gzio.o + -rm -f $@ + $(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gzio_mod-io_gzio.o + +mod-gzio.o: mod-gzio.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -c -o $@ $< + +mod-gzio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'gzio' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(gzio_mod_EXPORTS),no) +def-gzio.lst: pre-gzio.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gzio/' > $@ +endif + +und-gzio.lst: pre-gzio.o + echo 'gzio' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +gzio_mod-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -MD -c -o $@ $< +-include gzio_mod-io_gzio.d + +CLEANFILES += cmd-gzio_mod-io_gzio.lst fs-gzio_mod-io_gzio.lst partmap-gzio_mod-io_gzio.lst +COMMANDFILES += cmd-gzio_mod-io_gzio.lst +FSFILES += fs-gzio_mod-io_gzio.lst +PARTMAPFILES += partmap-gzio_mod-io_gzio.lst + +cmd-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh gzio > $@ || (rm -f $@; exit 1) + +fs-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh gzio > $@ || (rm -f $@; exit 1) + +partmap-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh gzio > $@ || (rm -f $@; exit 1) + + +gzio_mod_CFLAGS = $(COMMON_CFLAGS) +gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bufio.mod. +bufio_mod_SOURCES = io/bufio.c +CLEANFILES += bufio.mod mod-bufio.o mod-bufio.c pre-bufio.o bufio_mod-io_bufio.o und-bufio.lst +ifneq ($(bufio_mod_EXPORTS),no) +CLEANFILES += def-bufio.lst +DEFSYMFILES += def-bufio.lst +endif +MOSTLYCLEANFILES += bufio_mod-io_bufio.d +UNDSYMFILES += und-bufio.lst + +bufio.mod: pre-bufio.o mod-bufio.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(bufio_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-bufio.o mod-bufio.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-bufio.o: $(bufio_mod_DEPENDENCIES) bufio_mod-io_bufio.o + -rm -f $@ + $(TARGET_CC) $(bufio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bufio_mod-io_bufio.o + +mod-bufio.o: mod-bufio.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -c -o $@ $< + +mod-bufio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'bufio' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(bufio_mod_EXPORTS),no) +def-bufio.lst: pre-bufio.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bufio/' > $@ +endif + +und-bufio.lst: pre-bufio.o + echo 'bufio' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +bufio_mod-io_bufio.o: io/bufio.c $(io/bufio.c_DEPENDENCIES) + $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -MD -c -o $@ $< +-include bufio_mod-io_bufio.d + +CLEANFILES += cmd-bufio_mod-io_bufio.lst fs-bufio_mod-io_bufio.lst partmap-bufio_mod-io_bufio.lst +COMMANDFILES += cmd-bufio_mod-io_bufio.lst +FSFILES += fs-bufio_mod-io_bufio.lst +PARTMAPFILES += partmap-bufio_mod-io_bufio.lst + +cmd-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh bufio > $@ || (rm -f $@; exit 1) + +fs-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh bufio > $@ || (rm -f $@; exit 1) + +partmap-bufio_mod-io_bufio.lst: io/bufio.c $(io/bufio.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bufio_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh bufio > $@ || (rm -f $@; exit 1) + + +bufio_mod_CFLAGS = $(COMMON_CFLAGS) +bufio_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/common.rmk b/conf/common.rmk new file mode 100644 index 0000000..dfd481a --- /dev/null +++ b/conf/common.rmk @@ -0,0 +1,499 @@ +# -*- makefile -*- + +# For grub-mkelfimage. +bin_UTILITIES += grub-mkelfimage +grub_mkelfimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \ + util/resolve.c +util/elf/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-probe. +sbin_UTILITIES += grub-probe +util/grub-probe.c_DEPENDENCIES = grub_probe_init.h +grub_probe_SOURCES = util/grub-probe.c \ + util/hostdisk.c util/misc.c util/getroot.c \ + kern/device.c kern/disk.c kern/err.c kern/misc.c \ + kern/parser.c kern/partition.c kern/file.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + partmap/pc.c partmap/apple.c partmap/gpt.c \ + kern/fs.c kern/env.c fs/fshelp.c \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c + +ifeq ($(enable_grub_fstest), yes) +bin_UTILITIES += grub-fstest +endif + +# For grub-fstest. +util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h +grub_fstest_SOURCES = util/grub-fstest.c util/hostfs.c util/misc.c \ + kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ + disk/host.c disk/loopback.c normal/arg.c normal/misc.c \ + lib/hexdump.c lib/crc.c commands/blocklist.c commands/ls.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + kern/partition.c partmap/pc.c partmap/apple.c partmap/gpt.c \ + kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \ + disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_fstest_init.c + +# For grub-mkfont. +ifeq ($(enable_grub_mkfont), yes) +bin_UTILITIES += grub-mkfont +grub_mkfont_SOURCES = util/grub-mkfont.c util/misc.c +grub_mkfont_CFLAGS = $(freetype_cflags) +grub_mkfont_LDFLAGS = $(freetype_libs) +endif + +# For the parser. +grub_script.tab.c grub_script.tab.h: normal/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y +DISTCLEANFILES += grub_script.tab.c grub_script.tab.h + +# For grub-emu. +grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_emu_init.lst + +grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_emu_init.h + +grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_emu_init.c + +# For grub-probe. +grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_probe_init.lst + +grub_probe_init.h: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_probe_init.h + +grub_probe_init.c: grub_probe_init.lst $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) geninit.sh grub_probe_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_probe_init.c + +# For grub-setup. +grub_setup_init.lst: geninit.sh $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_setup_init.lst + +grub_setup_init.h: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_setup_init.h + +grub_setup_init.c: grub_setup_init.lst $(filter-out grub_setup_init.c,$(grub_setup_SOURCES)) geninit.sh grub_setup_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_setup_init.c + +# For grub-fstest. +grub_fstest_init.lst: geninit.sh $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_fstest_init.lst + +grub_fstest_init.h: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_fstest_init.h + +grub_fstest_init.c: grub_fstest_init.lst $(filter-out grub_fstest_init.c,$(grub_fstest_SOURCES)) geninit.sh grub_fstest_init.h + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_fstest_init.c + +# for grub-editenv +bin_UTILITIES += grub-editenv +grub_editenv_SOURCES = util/grub-editenv.c lib/envblk.c util/misc.c kern/misc.c kern/err.c +CLEANFILES += grub-editenv + +# for grub-pe2elf +ifeq ($(enable_grub_pe2elf), yes) +bin_UTILITIES += grub-pe2elf +endif + +grub_pe2elf_SOURCES = util/grub-pe2elf.c util/misc.c +CLEANFILES += grub-pe2elf + +# For grub-mkconfig +grub-mkconfig: util/grub-mkconfig.in config.status + ./config.status --file=$@:$< + chmod +x $@ +sbin_SCRIPTS += grub-mkconfig +CLEANFILES += grub-mkconfig + +grub-mkconfig_lib: util/grub-mkconfig_lib.in config.status + ./config.status --file=$@:$< + chmod +x $@ +lib_DATA += grub-mkconfig_lib +CLEANFILES += grub-mkconfig_lib + +update-grub_lib: util/update-grub_lib.in config.status + ./config.status --file=$@:$< + chmod +x $@ +lib_DATA += update-grub_lib +CLEANFILES += update-grub_lib + +%: util/grub.d/%.in config.status + ./config.status --file=$@:$< + chmod +x $@ +grub-mkconfig_SCRIPTS = 00_header 10_linux 10_hurd 10_freebsd 30_os-prober 40_custom +ifeq ($(host_os), cygwin) +grub-mkconfig_SCRIPTS += 10_windows +endif + +CLEANFILES += $(grub-mkconfig_SCRIPTS) + +grub-mkconfig_DATA += util/grub.d/README + + +# Filing systems. +pkglib_MODULES += fshelp.mod fat.mod ufs.mod ext2.mod ntfs.mod \ + ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod \ + affs.mod sfs.mod hfsplus.mod reiserfs.mod cpio.mod tar.mod \ + udf.mod afs.mod + +# For fshelp.mod. +fshelp_mod_SOURCES = fs/fshelp.c +fshelp_mod_CFLAGS = $(COMMON_CFLAGS) +fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +fat_mod_CFLAGS = $(COMMON_CFLAGS) +fat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ufs.mod. +ufs_mod_SOURCES = fs/ufs.c +ufs_mod_CFLAGS = $(COMMON_CFLAGS) +ufs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ext2.mod. +ext2_mod_SOURCES = fs/ext2.c +ext2_mod_CFLAGS = $(COMMON_CFLAGS) +ext2_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ntfs.mod. +ntfs_mod_SOURCES = fs/ntfs.c +ntfs_mod_CFLAGS = $(COMMON_CFLAGS) +ntfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ntfscomp.mod. +ntfscomp_mod_SOURCES = fs/ntfscomp.c +ntfscomp_mod_CFLAGS = $(COMMON_CFLAGS) +ntfscomp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For minix.mod. +minix_mod_SOURCES = fs/minix.c +minix_mod_CFLAGS = $(COMMON_CFLAGS) +minix_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfs.mod. +hfs_mod_SOURCES = fs/hfs.c +hfs_mod_CFLAGS = $(COMMON_CFLAGS) +hfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jfs.mod. +jfs_mod_SOURCES = fs/jfs.c +jfs_mod_CFLAGS = $(COMMON_CFLAGS) +jfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For iso9660.mod. +iso9660_mod_SOURCES = fs/iso9660.c +iso9660_mod_CFLAGS = $(COMMON_CFLAGS) +iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For xfs.mod. +xfs_mod_SOURCES = fs/xfs.c +xfs_mod_CFLAGS = $(COMMON_CFLAGS) +xfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For affs.mod. +affs_mod_SOURCES = fs/affs.c +affs_mod_CFLAGS = $(COMMON_CFLAGS) +affs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sfs.mod. +sfs_mod_SOURCES = fs/sfs.c +sfs_mod_CFLAGS = $(COMMON_CFLAGS) +sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfsplus.mod. +hfsplus_mod_SOURCES = fs/hfsplus.c +hfsplus_mod_CFLAGS = $(COMMON_CFLAGS) +hfsplus_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reiserfs.mod. +reiserfs_mod_SOURCES = fs/reiserfs.c +reiserfs_mod_CFLAGS = $(COMMON_CFLAGS) +reiserfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cpio.mod. +cpio_mod_SOURCES = fs/cpio.c +cpio_mod_CFLAGS = $(COMMON_CFLAGS) +cpio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For tar.mod. +tar_mod_SOURCES = fs/cpio.c +tar_mod_CFLAGS = $(COMMON_CFLAGS) -DMODE_USTAR +tar_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For udf.mod. +udf_mod_SOURCES = fs/udf.c +udf_mod_CFLAGS = $(COMMON_CFLAGS) +udf_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For afs.mod. +afs_mod_SOURCES = fs/afs.c +afs_mod_CFLAGS = $(COMMON_CFLAGS) +afs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Partition maps. +pkglib_MODULES += amiga.mod apple.mod pc.mod sun.mod acorn.mod gpt.mod + +# For amiga.mod +amiga_mod_SOURCES = partmap/amiga.c +amiga_mod_CFLAGS = $(COMMON_CFLAGS) +amiga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For apple.mod +apple_mod_SOURCES = partmap/apple.c +apple_mod_CFLAGS = $(COMMON_CFLAGS) +apple_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pc.mod +pc_mod_SOURCES = partmap/pc.c +pc_mod_CFLAGS = $(COMMON_CFLAGS) +pc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sun.mod +sun_mod_SOURCES = partmap/sun.c +sun_mod_CFLAGS = $(COMMON_CFLAGS) +sun_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For acorn.mod +acorn_mod_SOURCES = partmap/acorn.c +acorn_mod_CFLAGS = $(COMMON_CFLAGS) +acorn_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gpt.mod +gpt_mod_SOURCES = partmap/gpt.c +gpt_mod_CFLAGS = $(COMMON_CFLAGS) +gpt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Special disk structures and generic drivers + +pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \ + lvm.mod scsi.mod + +# For raid.mod +raid_mod_SOURCES = disk/raid.c +raid_mod_CFLAGS = $(COMMON_CFLAGS) +raid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For raid5rec.mod +raid5rec_mod_SOURCES = disk/raid5_recover.c +raid5rec_mod_CFLAGS = $(COMMON_CFLAGS) +raid5rec_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For raid6rec.mod +raid6rec_mod_SOURCES = disk/raid6_recover.c +raid6rec_mod_CFLAGS = $(COMMON_CFLAGS) +raid6rec_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For mdraid.mod +mdraid_mod_SOURCES = disk/mdraid_linux.c +mdraid_mod_CFLAGS = $(COMMON_CFLAGS) +mdraid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For dm_nv.mod +dm_nv_mod_SOURCES = disk/dmraid_nvidia.c +dm_nv_mod_CFLAGS = $(COMMON_CFLAGS) +dm_nv_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lvm.mod +lvm_mod_SOURCES = disk/lvm.c +lvm_mod_CFLAGS = $(COMMON_CFLAGS) +lvm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For scsi.mod +scsi_mod_SOURCES = disk/scsi.c +scsi_mod_CFLAGS = $(COMMON_CFLAGS) +scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Commands. +pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \ + cmp.mod cat.mod help.mod search.mod \ + loopback.mod fs_uuid.mod configfile.mod echo.mod \ + terminfo.mod test.mod blocklist.mod hexdump.mod \ + read.mod sleep.mod loadenv.mod crc.mod + +# For hello.mod. +hello_mod_SOURCES = hello/hello.c +hello_mod_CFLAGS = $(COMMON_CFLAGS) +hello_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For boot.mod. +boot_mod_SOURCES = commands/boot.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminal.mod. +terminal_mod_SOURCES = commands/terminal.c +terminal_mod_CFLAGS = $(COMMON_CFLAGS) +terminal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ls.mod. +ls_mod_SOURCES = commands/ls.c +ls_mod_CFLAGS = $(COMMON_CFLAGS) +ls_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cmp.mod. +cmp_mod_SOURCES = commands/cmp.c +cmp_mod_CFLAGS = $(COMMON_CFLAGS) +cmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cat.mod. +cat_mod_SOURCES = commands/cat.c +cat_mod_CFLAGS = $(COMMON_CFLAGS) +cat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For echo.mod +echo_mod_SOURCES = commands/echo.c +echo_mod_CFLAGS = $(COMMON_CFLAGS) +echo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For help.mod. +help_mod_SOURCES = commands/help.c +help_mod_CFLAGS = $(COMMON_CFLAGS) +help_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For search.mod. +search_mod_SOURCES = commands/search.c +search_mod_CFLAGS = $(COMMON_CFLAGS) +search_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For test.mod. +test_mod_SOURCES = commands/test.c +test_mod_CFLAGS = $(COMMON_CFLAGS) +test_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For loopback.mod +loopback_mod_SOURCES = disk/loopback.c +loopback_mod_CFLAGS = $(COMMON_CFLAGS) +loopback_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fs_uuid.mod +fs_uuid_mod_SOURCES = disk/fs_uuid.c +fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS) +fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For configfile.mod +configfile_mod_SOURCES = commands/configfile.c +configfile_mod_CFLAGS = $(COMMON_CFLAGS) +configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminfo.mod. +terminfo_mod_SOURCES = term/terminfo.c term/tparm.c +terminfo_mod_CFLAGS = $(COMMON_CFLAGS) +terminfo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For blocklist.mod. +blocklist_mod_SOURCES = commands/blocklist.c +blocklist_mod_CFLAGS = $(COMMON_CFLAGS) +blocklist_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hexdump.mod. +hexdump_mod_SOURCES = commands/hexdump.c lib/hexdump.c +hexdump_mod_CFLAGS = $(COMMON_CFLAGS) +hexdump_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For read.mod. +read_mod_SOURCES = commands/read.c +read_mod_CFLAGS = $(COMMON_CFLAGS) +read_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sleep.mod. +sleep_mod_SOURCES = commands/sleep.c +sleep_mod_CFLAGS = $(COMMON_CFLAGS) +sleep_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For loadenv.mod. +loadenv_mod_SOURCES = commands/loadenv.c lib/envblk.c +loadenv_mod_CFLAGS = $(COMMON_CFLAGS) +loadenv_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For crc.mod. +crc_mod_SOURCES = commands/crc.c lib/crc.c +crc_mod_CFLAGS = $(COMMON_CFLAGS) +crc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Common Video Subsystem specific modules. +pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \ + png.mod font.mod gfxterm.mod + +# For video.mod. +video_mod_SOURCES = video/video.c +video_mod_CFLAGS = $(COMMON_CFLAGS) +video_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For videotest.mod. +videotest_mod_SOURCES = commands/videotest.c +videotest_mod_CFLAGS = $(COMMON_CFLAGS) +videotest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bitmap.mod +bitmap_mod_SOURCES = video/bitmap.c +bitmap_mod_CFLAGS = $(COMMON_CFLAGS) +bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For tga.mod +tga_mod_SOURCES = video/readers/tga.c +tga_mod_CFLAGS = $(COMMON_CFLAGS) +tga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jpeg.mod. +jpeg_mod_SOURCES = video/readers/jpeg.c +jpeg_mod_CFLAGS = $(COMMON_CFLAGS) +jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For png.mod. +png_mod_SOURCES = video/readers/png.c +png_mod_CFLAGS = $(COMMON_CFLAGS) +png_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For font.mod. +font_mod_SOURCES = font/font_cmd.c font/font.c +font_mod_CFLAGS = $(COMMON_CFLAGS) +font_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gfxterm.mod. +gfxterm_mod_SOURCES = term/gfxterm.c +gfxterm_mod_CFLAGS = $(COMMON_CFLAGS) +gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# Misc. +pkglib_MODULES += gzio.mod bufio.mod elf.mod + +# For elf.mod. +elf_mod_SOURCES = kern/elf.c +elf_mod_CFLAGS = $(COMMON_CFLAGS) +elf_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gzio.mod. +gzio_mod_SOURCES = io/gzio.c +gzio_mod_CFLAGS = $(COMMON_CFLAGS) +gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bufio.mod. +bufio_mod_SOURCES = io/bufio.c +bufio_mod_CFLAGS = $(COMMON_CFLAGS) +bufio_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.mk b/conf/i386-coreboot.mk new file mode 100644 index 0000000..c10d16f --- /dev/null +++ b/conf/i386-coreboot.mk @@ -0,0 +1,2062 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_PROGRAMS = kernel.elf + +# For kernel.elf. +kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ + kern/i386/coreboot/init.c \ + kern/i386/multiboot_mmap.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/time.c \ + kern/i386/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/vga_text.c term/i386/vga_common.c \ + term/i386/pc/at_keyboard.c \ + symlist.c +CLEANFILES += kernel.elf kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-term_i386_vga_common.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-symlist.o +MOSTLYCLEANFILES += kernel_elf-kern_i386_coreboot_startup.d kernel_elf-kern_i386_coreboot_init.d kernel_elf-kern_i386_multiboot_mmap.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_time.d kernel_elf-kern_i386_dl.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_i386_tsc.d kernel_elf-kern_i386_pit.d kernel_elf-kern_generic_rtc_get_time_ms.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_env.d kernel_elf-term_i386_pc_vga_text.d kernel_elf-term_i386_vga_common.d kernel_elf-term_i386_pc_at_keyboard.d kernel_elf-symlist.d + +kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-term_i386_vga_common.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-symlist.o + $(TARGET_CC) -o $@ kernel_elf-kern_i386_coreboot_startup.o kernel_elf-kern_i386_coreboot_init.o kernel_elf-kern_i386_multiboot_mmap.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_time.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_i386_tsc.o kernel_elf-kern_i386_pit.o kernel_elf-kern_generic_rtc_get_time_ms.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_env.o kernel_elf-term_i386_pc_vga_text.o kernel_elf-term_i386_vga_common.o kernel_elf-term_i386_pc_at_keyboard.o kernel_elf-symlist.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) + +kernel_elf-kern_i386_coreboot_startup.o: kern/i386/coreboot/startup.S $(kern/i386/coreboot/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_coreboot_startup.d + +kernel_elf-kern_i386_coreboot_init.o: kern/i386/coreboot/init.c $(kern/i386/coreboot/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/coreboot -I$(srcdir)/kern/i386/coreboot $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_coreboot_init.d + +kernel_elf-kern_i386_multiboot_mmap.o: kern/i386/multiboot_mmap.c $(kern/i386/multiboot_mmap.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_multiboot_mmap.d + +kernel_elf-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_main.d + +kernel_elf-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_device.d + +kernel_elf-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_disk.d + +kernel_elf-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_dl.d + +kernel_elf-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_file.d + +kernel_elf-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_fs.d + +kernel_elf-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_err.d + +kernel_elf-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_misc.d + +kernel_elf-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_mm.d + +kernel_elf-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_loader.d + +kernel_elf-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_rescue.d + +kernel_elf-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_term.d + +kernel_elf-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_time.d + +kernel_elf-kern_i386_dl.o: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_dl.d + +kernel_elf-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_parser.d + +kernel_elf-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_partition.d + +kernel_elf-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_tsc.d + +kernel_elf-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_pit.d + +kernel_elf-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_rtc_get_time_ms.d + +kernel_elf-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_millisleep.d + +kernel_elf-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_env.d + +kernel_elf-term_i386_pc_vga_text.o: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_i386_pc_vga_text.d + +kernel_elf-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_i386_vga_common.d + +kernel_elf-term_i386_pc_at_keyboard.o: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_i386_pc_at_keyboard.d + +kernel_elf-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-symlist.d + +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c +CLEANFILES += grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o +MOSTLYCLEANFILES += grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_misc.d + +grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o + $(CC) -o $@ grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS) + +grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_grub_mkdevicemap.d + +grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_misc.d + + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/i386/cpuid.c \ + disk/host.c disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + fs/fshelp.c \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/menu_text.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c +CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o +MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_i386_cpuid.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_menu_text.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-normal_color.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_i386_pc_misc.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d + +grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o + $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS) + +grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_boot.d + +grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cat.d + +grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cmp.d + +grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_configfile.d + +grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_echo.d + +grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_help.d + +grub_emu-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_terminal.d + +grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_ls.d + +grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_test.d + +grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_search.d + +grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_blocklist.d + +grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_hexdump.d + +grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-lib_hexdump.d + +grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) + $(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_i386_cpuid.d + +grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_host.d + +grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_loopback.d + +grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_affs.d + +grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_cpio.d + +grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fat.d + +grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ext2.d + +grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfs.d + +grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfsplus.d + +grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_iso9660.d + +grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_udf.d + +grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_jfs.d + +grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_minix.d + +grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfs.d + +grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfscomp.d + +grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_reiserfs.d + +grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_sfs.d + +grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ufs.d + +grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_xfs.d + +grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_afs.d + +grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_tar.d + +grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fshelp.d + +grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-io_gzio.d + +grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_device.d + +grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_disk.d + +grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_dl.d + +grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_elf.d + +grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_env.d + +grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_err.d + +grub_emu-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_execute.d + +grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_file.d + +grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_fs.d + +grub_emu-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_lexer.d + +grub_emu-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_loader.d + +grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_main.d + +grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_misc.d + +grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_parser.d + +grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_script_tab.d + +grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_partition.d + +grub_emu-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_rescue.d + +grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_term.d + +grub_emu-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_arg.d + +grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_cmdline.d + +grub_emu-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_command.d + +grub_emu-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_function.d + +grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_completion.d + +grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_main.d + +grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_text.d + +grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu.d + +grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_entry.d + +grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_viewer.d + +grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_misc.d + +grub_emu-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_script.d + +grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_color.d + +grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_amiga.d + +grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_apple.d + +grub_emu-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_pc.d + +grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_sun.d + +grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_acorn.d + +grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_gpt.d + +grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_console.d + +grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostfs.d + +grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_grub_emu.d + +grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_misc.d + +grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostdisk.d + +grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_getroot.d + +grub_emu-util_i386_pc_misc.o: util/i386/pc/misc.c $(util/i386/pc/misc.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_i386_pc_misc.d + +grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid.d + +grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid5_recover.d + +grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid6_recover.d + +grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_mdraid_linux.d + +grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_dmraid_nvidia.d + +grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_lvm.d + +grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_emu_init.d + + +grub_emu_LDFLAGS = $(LIBCURSES) + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/i386/pc/grub-install.in +CLEANFILES += grub-install + +grub-install: util/i386/pc/grub-install.in $(util/i386/pc/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/i386/pc/grub-install.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = _linux.mod linux.mod normal.mod \ + _multiboot.mod multiboot.mod aout.mod \ + play.mod serial.mod ata.mod \ + memdisk.mod pci.mod lspci.mod reboot.mod \ + halt.mod datetime.mod date.mod datehook.mod \ + lsmmap.mod + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_i386_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_i386_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_i386_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_i386_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_i386_linux.o: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_i386_linux.d + +CLEANFILES += cmd-_linux_mod-loader_i386_linux.lst fs-_linux_mod-loader_i386_linux.lst partmap-_linux_mod-loader_i386_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_i386_linux.lst +FSFILES += fs-_linux_mod-loader_i386_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_i386_linux.lst + +cmd-_linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_i386_linux.lst: loader/i386/linux.c $(loader/i386/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_linux_normal.o: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_linux_normal.lst fs-linux_mod-loader_linux_normal.lst partmap-linux_mod-loader_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_linux_normal.lst +FSFILES += fs-linux_mod-loader_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_linux_normal.lst + +cmd-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_i386_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_i386_setjmp.o: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_i386_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_i386_setjmp.lst fs-normal_mod-normal_i386_setjmp.lst partmap-normal_mod-normal_i386_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_i386_setjmp.lst +FSFILES += fs-normal_mod-normal_i386_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_i386_setjmp.lst + +cmd-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d reboot_mod-kern_i386_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o reboot_mod-kern_i386_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod-kern_i386_reboot.o: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-kern_i386_reboot.d + +CLEANFILES += cmd-reboot_mod-kern_i386_reboot.lst fs-reboot_mod-kern_i386_reboot.lst partmap-reboot_mod-kern_i386_reboot.lst +COMMANDFILES += cmd-reboot_mod-kern_i386_reboot.lst +FSFILES += fs-reboot_mod-kern_i386_reboot.lst +PARTMAPFILES += partmap-reboot_mod-kern_i386_reboot.lst + +cmd-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-kern_i386_reboot.lst: kern/i386/reboot.c $(kern/i386/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c kern/i386/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o halt_mod-kern_i386_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d halt_mod-kern_i386_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o halt_mod-kern_i386_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o halt_mod-kern_i386_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod-kern_i386_halt.o: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-kern_i386_halt.d + +CLEANFILES += cmd-halt_mod-kern_i386_halt.lst fs-halt_mod-kern_i386_halt.lst partmap-halt_mod-kern_i386_halt.lst +COMMANDFILES += cmd-halt_mod-kern_i386_halt.lst +FSFILES += fs-halt_mod-kern_i386_halt.lst +PARTMAPFILES += partmap-halt_mod-kern_i386_halt.lst + +cmd-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-kern_i386_halt.lst: kern/i386/halt.c $(kern/i386/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +CLEANFILES += serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst +ifneq ($(serial_mod_EXPORTS),no) +CLEANFILES += def-serial.lst +DEFSYMFILES += def-serial.lst +endif +MOSTLYCLEANFILES += serial_mod-term_i386_pc_serial.d +UNDSYMFILES += und-serial.lst + +serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o + +mod-serial.o: mod-serial.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $< + +mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(serial_mod_EXPORTS),no) +def-serial.lst: pre-serial.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@ +endif + +und-serial.lst: pre-serial.o + echo 'serial' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $< +-include serial_mod-term_i386_pc_serial.d + +CLEANFILES += cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst +COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst +FSFILES += fs-serial_mod-term_i386_pc_serial.lst +PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst + +cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1) + +fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1) + +partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1) + + +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \ + loader/i386/pc/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst +ifneq ($(_multiboot_mod_EXPORTS),no) +CLEANFILES += def-_multiboot.lst +DEFSYMFILES += def-_multiboot.lst +endif +MOSTLYCLEANFILES += _multiboot_mod-loader_i386_pc_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d +UNDSYMFILES += und-_multiboot.lst + +_multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_multiboot.o mod-_multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + +mod-_multiboot.o: mod-_multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $< + +mod-_multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_multiboot_mod_EXPORTS),no) +def-_multiboot.lst: pre-_multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _multiboot/' > $@ +endif + +und-_multiboot.lst: pre-_multiboot.o + echo '_multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_multiboot_mod-loader_i386_pc_multiboot.o: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_i386_pc_multiboot.d + +CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst fs-_multiboot_mod-loader_i386_pc_multiboot.lst partmap-_multiboot_mod-loader_i386_pc_multiboot.lst +COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst +FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot.lst + +cmd-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_i386_pc_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst fs-_multiboot_mod-loader_i386_pc_multiboot2.lst partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst + +cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot2.lst fs-_multiboot_mod-loader_multiboot2.lst partmap-_multiboot_mod-loader_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot2.lst + +cmd-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot_loader.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst fs-_multiboot_mod-loader_multiboot_loader.lst partmap-_multiboot_mod-loader_multiboot_loader.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst +FSFILES += fs-_multiboot_mod-loader_multiboot_loader.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot_loader.lst + +cmd-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +CLEANFILES += multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_multiboot_loader_normal.o und-multiboot.lst +ifneq ($(multiboot_mod_EXPORTS),no) +CLEANFILES += def-multiboot.lst +DEFSYMFILES += def-multiboot.lst +endif +MOSTLYCLEANFILES += multiboot_mod-loader_multiboot_loader_normal.d +UNDSYMFILES += und-multiboot.lst + +multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_multiboot_loader_normal.o + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_multiboot_loader_normal.o + +mod-multiboot.o: mod-multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(multiboot_mod_EXPORTS),no) +def-multiboot.lst: pre-multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@ +endif + +und-multiboot.lst: pre-multiboot.o + echo 'multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +multiboot_mod-loader_multiboot_loader_normal.o: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include multiboot_mod-loader_multiboot_loader_normal.d + +CLEANFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst fs-multiboot_mod-loader_multiboot_loader_normal.lst partmap-multiboot_mod-loader_multiboot_loader_normal.lst +COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst +FSFILES += fs-multiboot_mod-loader_multiboot_loader_normal.lst +PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader_normal.lst + +cmd-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1) + +fs-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1) + +partmap-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1) + + +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +CLEANFILES += aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst +ifneq ($(aout_mod_EXPORTS),no) +CLEANFILES += def-aout.lst +DEFSYMFILES += def-aout.lst +endif +MOSTLYCLEANFILES += aout_mod-loader_aout.d +UNDSYMFILES += und-aout.lst + +aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o + +mod-aout.o: mod-aout.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $< + +mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(aout_mod_EXPORTS),no) +def-aout.lst: pre-aout.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@ +endif + +und-aout.lst: pre-aout.o + echo 'aout' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $< +-include aout_mod-loader_aout.d + +CLEANFILES += cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst +COMMANDFILES += cmd-aout_mod-loader_aout.lst +FSFILES += fs-aout_mod-loader_aout.lst +PARTMAPFILES += partmap-aout_mod-loader_aout.lst + +cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1) + +fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1) + +partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1) + + +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +CLEANFILES += play.mod mod-play.o mod-play.c pre-play.o play_mod-commands_i386_pc_play.o und-play.lst +ifneq ($(play_mod_EXPORTS),no) +CLEANFILES += def-play.lst +DEFSYMFILES += def-play.lst +endif +MOSTLYCLEANFILES += play_mod-commands_i386_pc_play.d +UNDSYMFILES += und-play.lst + +play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-play.o mod-play.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-play.o: $(play_mod_DEPENDENCIES) play_mod-commands_i386_pc_play.o + -rm -f $@ + $(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ play_mod-commands_i386_pc_play.o + +mod-play.o: mod-play.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -c -o $@ $< + +mod-play.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'play' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(play_mod_EXPORTS),no) +def-play.lst: pre-play.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 play/' > $@ +endif + +und-play.lst: pre-play.o + echo 'play' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +play_mod-commands_i386_pc_play.o: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -MD -c -o $@ $< +-include play_mod-commands_i386_pc_play.d + +CLEANFILES += cmd-play_mod-commands_i386_pc_play.lst fs-play_mod-commands_i386_pc_play.lst partmap-play_mod-commands_i386_pc_play.lst +COMMANDFILES += cmd-play_mod-commands_i386_pc_play.lst +FSFILES += fs-play_mod-commands_i386_pc_play.lst +PARTMAPFILES += partmap-play_mod-commands_i386_pc_play.lst + +cmd-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh play > $@ || (rm -f $@; exit 1) + +fs-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh play > $@ || (rm -f $@; exit 1) + +partmap-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh play > $@ || (rm -f $@; exit 1) + + +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata.mod. +ata_mod_SOURCES = disk/ata.c +CLEANFILES += ata.mod mod-ata.o mod-ata.c pre-ata.o ata_mod-disk_ata.o und-ata.lst +ifneq ($(ata_mod_EXPORTS),no) +CLEANFILES += def-ata.lst +DEFSYMFILES += def-ata.lst +endif +MOSTLYCLEANFILES += ata_mod-disk_ata.d +UNDSYMFILES += und-ata.lst + +ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ata.o mod-ata.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ata.o: $(ata_mod_DEPENDENCIES) ata_mod-disk_ata.o + -rm -f $@ + $(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_mod-disk_ata.o + +mod-ata.o: mod-ata.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -c -o $@ $< + +mod-ata.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ata' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ata_mod_EXPORTS),no) +def-ata.lst: pre-ata.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata/' > $@ +endif + +und-ata.lst: pre-ata.o + echo 'ata' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ata_mod-disk_ata.o: disk/ata.c $(disk/ata.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -MD -c -o $@ $< +-include ata_mod-disk_ata.d + +CLEANFILES += cmd-ata_mod-disk_ata.lst fs-ata_mod-disk_ata.lst partmap-ata_mod-disk_ata.lst +COMMANDFILES += cmd-ata_mod-disk_ata.lst +FSFILES += fs-ata_mod-disk_ata.lst +PARTMAPFILES += partmap-ata_mod-disk_ata.lst + +cmd-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ata > $@ || (rm -f $@; exit 1) + +fs-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ata > $@ || (rm -f $@; exit 1) + +partmap-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ata > $@ || (rm -f $@; exit 1) + + +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst +PARTMAPFILES += partmap-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + +partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst +PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + +partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +CLEANFILES += datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst +ifneq ($(datetime_mod_EXPORTS),no) +CLEANFILES += def-datetime.lst +DEFSYMFILES += def-datetime.lst +endif +MOSTLYCLEANFILES += datetime_mod-lib_datetime.d datetime_mod-lib_i386_datetime.d +UNDSYMFILES += und-datetime.lst + +datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + +mod-datetime.o: mod-datetime.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $< + +mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datetime_mod_EXPORTS),no) +def-datetime.lst: pre-datetime.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@ +endif + +und-datetime.lst: pre-datetime.o + echo 'datetime' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datetime_mod-lib_datetime.o: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_datetime.lst fs-datetime_mod-lib_datetime.lst partmap-datetime_mod-lib_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_datetime.lst +FSFILES += fs-datetime_mod-lib_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_datetime.lst + +cmd-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_i386_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst +FSFILES += fs-datetime_mod-lib_i386_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst + +cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +CLEANFILES += date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst +ifneq ($(date_mod_EXPORTS),no) +CLEANFILES += def-date.lst +DEFSYMFILES += def-date.lst +endif +MOSTLYCLEANFILES += date_mod-commands_date.d +UNDSYMFILES += und-date.lst + +date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o + +mod-date.o: mod-date.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $< + +mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(date_mod_EXPORTS),no) +def-date.lst: pre-date.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@ +endif + +und-date.lst: pre-date.o + echo 'date' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $< +-include date_mod-commands_date.d + +CLEANFILES += cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst +COMMANDFILES += cmd-date_mod-commands_date.lst +FSFILES += fs-date_mod-commands_date.lst +PARTMAPFILES += partmap-date_mod-commands_date.lst + +cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1) + +fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1) + +partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1) + + +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +CLEANFILES += datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst +ifneq ($(datehook_mod_EXPORTS),no) +CLEANFILES += def-datehook.lst +DEFSYMFILES += def-datehook.lst +endif +MOSTLYCLEANFILES += datehook_mod-hook_datehook.d +UNDSYMFILES += und-datehook.lst + +datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o + +mod-datehook.o: mod-datehook.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $< + +mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datehook_mod_EXPORTS),no) +def-datehook.lst: pre-datehook.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@ +endif + +und-datehook.lst: pre-datehook.o + echo 'datehook' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) + $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $< +-include datehook_mod-hook_datehook.d + +CLEANFILES += cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst +COMMANDFILES += cmd-datehook_mod-hook_datehook.lst +FSFILES += fs-datehook_mod-hook_datehook.lst +PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst + +cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1) + +fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1) + +partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1) + + +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +CLEANFILES += lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst +ifneq ($(lsmmap_mod_EXPORTS),no) +CLEANFILES += def-lsmmap.lst +DEFSYMFILES += def-lsmmap.lst +endif +MOSTLYCLEANFILES += lsmmap_mod-commands_lsmmap.d +UNDSYMFILES += und-lsmmap.lst + +lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o + +mod-lsmmap.o: mod-lsmmap.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $< + +mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lsmmap_mod_EXPORTS),no) +def-lsmmap.lst: pre-lsmmap.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@ +endif + +und-lsmmap.lst: pre-lsmmap.o + echo 'lsmmap' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $< +-include lsmmap_mod-commands_lsmmap.d + +CLEANFILES += cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst +COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst +FSFILES += fs-lsmmap_mod-commands_lsmmap.lst +PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst + +cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1) + +fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1) + +partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1) + + +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk new file mode 100644 index 0000000..b97483b --- /dev/null +++ b/conf/i386-coreboot.rmk @@ -0,0 +1,215 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_PROGRAMS = kernel.elf + +# For kernel.elf. +kernel_elf_SOURCES = kern/i386/coreboot/startup.S \ + kern/i386/coreboot/init.c \ + kern/i386/multiboot_mmap.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/time.c \ + kern/i386/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/vga_text.c term/i386/vga_common.c \ + term/i386/pc/at_keyboard.c \ + symlist.c +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/i386/cpuid.c \ + disk/host.c disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + fs/fshelp.c \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/menu_text.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/i386/pc/grub-install.in + +# Modules. +pkglib_MODULES = _linux.mod linux.mod normal.mod \ + _multiboot.mod multiboot.mod aout.mod \ + play.mod serial.mod ata.mod \ + memdisk.mod pci.mod lspci.mod reboot.mod \ + halt.mod datetime.mod date.mod datehook.mod \ + lsmmap.mod + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c kern/i386/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \ + loader/i386/pc/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata.mod. +ata_mod_SOURCES = disk/ata.c +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-efi.mk b/conf/i386-efi.mk new file mode 100644 index 0000000..9e98098 --- /dev/null +++ b/conf/i386-efi.mk @@ -0,0 +1,1817 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -m32 +COMMON_LDFLAGS = -melf_i386 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Utilities. +bin_UTILITIES = grub-mkimage +sbin_UTILITIES = grub-mkdevicemap +#ifeq ($(enable_grub_emu), yes) +#sbin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \ + util/resolve.c +CLEANFILES += grub-mkimage$(EXEEXT) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o +MOSTLYCLEANFILES += grub_mkimage-util_i386_efi_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d + +grub-mkimage: $(grub_mkimage_DEPENDENCIES) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o + $(CC) -o $@ grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o $(LDFLAGS) $(grub_mkimage_LDFLAGS) + +grub_mkimage-util_i386_efi_grub_mkimage.o: util/i386/efi/grub-mkimage.c $(util/i386/efi/grub-mkimage.c_DEPENDENCIES) + $(CC) -Iutil/i386/efi -I$(srcdir)/util/i386/efi $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_i386_efi_grub_mkimage.d + +grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_misc.d + +grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_resolve.d + +util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-setup. +#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ +# util/misc.c util/getroot.c kern/device.c kern/disk.c \ +# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c \ +# fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c +CLEANFILES += grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o +MOSTLYCLEANFILES += grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_misc.d + +grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o + $(CC) -o $@ grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS) + +grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_grub_mkdevicemap.d + +grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_misc.d + + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/hexdump.c lib/hexdump.c \ + commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/context.c normal/main.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/efi/grub-install.in +CLEANFILES += grub-install + +grub-install: util/i386/efi/grub-install.in $(util/i386/efi/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/i386/efi/grub-install.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ + _linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod + +# For kernel.mod. +kernel_mod_EXPORTS = no +kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ + kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ + term/efi/console.c disk/efi/efidisk.c \ + kern/time.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c +CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o und-kernel.lst +ifneq ($(kernel_mod_EXPORTS),no) +CLEANFILES += def-kernel.lst +DEFSYMFILES += def-kernel.lst +endif +MOSTLYCLEANFILES += kernel_mod-kern_i386_efi_startup.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_i386_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-term_efi_console.d kernel_mod-disk_efi_efidisk.d kernel_mod-kern_time.d kernel_mod-kern_i386_tsc.d kernel_mod-kern_i386_pit.d kernel_mod-kern_generic_rtc_get_time_ms.d kernel_mod-kern_generic_millisleep.d +UNDSYMFILES += und-kernel.lst + +kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-kernel.o mod-kernel.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-kernel.o: $(kernel_mod_DEPENDENCIES) kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o + -rm -f $@ + $(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ kernel_mod-kern_i386_efi_startup.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_i386_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-kern_generic_millisleep.o + +mod-kernel.o: mod-kernel.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $< + +mod-kernel.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'kernel' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(kernel_mod_EXPORTS),no) +def-kernel.lst: pre-kernel.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 kernel/' > $@ +endif + +und-kernel.lst: pre-kernel.o + echo 'kernel' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +kernel_mod-kern_i386_efi_startup.o: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_efi_startup.d + +CLEANFILES += cmd-kernel_mod-kern_i386_efi_startup.lst fs-kernel_mod-kern_i386_efi_startup.lst partmap-kernel_mod-kern_i386_efi_startup.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_efi_startup.lst +FSFILES += fs-kernel_mod-kern_i386_efi_startup.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_startup.lst + +cmd-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_efi_startup.lst: kern/i386/efi/startup.S $(kern/i386/efi/startup.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_main.d + +CLEANFILES += cmd-kernel_mod-kern_main.lst fs-kernel_mod-kern_main.lst partmap-kernel_mod-kern_main.lst +COMMANDFILES += cmd-kernel_mod-kern_main.lst +FSFILES += fs-kernel_mod-kern_main.lst +PARTMAPFILES += partmap-kernel_mod-kern_main.lst + +cmd-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_device.d + +CLEANFILES += cmd-kernel_mod-kern_device.lst fs-kernel_mod-kern_device.lst partmap-kernel_mod-kern_device.lst +COMMANDFILES += cmd-kernel_mod-kern_device.lst +FSFILES += fs-kernel_mod-kern_device.lst +PARTMAPFILES += partmap-kernel_mod-kern_device.lst + +cmd-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_disk.d + +CLEANFILES += cmd-kernel_mod-kern_disk.lst fs-kernel_mod-kern_disk.lst partmap-kernel_mod-kern_disk.lst +COMMANDFILES += cmd-kernel_mod-kern_disk.lst +FSFILES += fs-kernel_mod-kern_disk.lst +PARTMAPFILES += partmap-kernel_mod-kern_disk.lst + +cmd-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_dl.d + +CLEANFILES += cmd-kernel_mod-kern_dl.lst fs-kernel_mod-kern_dl.lst partmap-kernel_mod-kern_dl.lst +COMMANDFILES += cmd-kernel_mod-kern_dl.lst +FSFILES += fs-kernel_mod-kern_dl.lst +PARTMAPFILES += partmap-kernel_mod-kern_dl.lst + +cmd-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_file.d + +CLEANFILES += cmd-kernel_mod-kern_file.lst fs-kernel_mod-kern_file.lst partmap-kernel_mod-kern_file.lst +COMMANDFILES += cmd-kernel_mod-kern_file.lst +FSFILES += fs-kernel_mod-kern_file.lst +PARTMAPFILES += partmap-kernel_mod-kern_file.lst + +cmd-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_fs.d + +CLEANFILES += cmd-kernel_mod-kern_fs.lst fs-kernel_mod-kern_fs.lst partmap-kernel_mod-kern_fs.lst +COMMANDFILES += cmd-kernel_mod-kern_fs.lst +FSFILES += fs-kernel_mod-kern_fs.lst +PARTMAPFILES += partmap-kernel_mod-kern_fs.lst + +cmd-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_err.d + +CLEANFILES += cmd-kernel_mod-kern_err.lst fs-kernel_mod-kern_err.lst partmap-kernel_mod-kern_err.lst +COMMANDFILES += cmd-kernel_mod-kern_err.lst +FSFILES += fs-kernel_mod-kern_err.lst +PARTMAPFILES += partmap-kernel_mod-kern_err.lst + +cmd-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_misc.d + +CLEANFILES += cmd-kernel_mod-kern_misc.lst fs-kernel_mod-kern_misc.lst partmap-kernel_mod-kern_misc.lst +COMMANDFILES += cmd-kernel_mod-kern_misc.lst +FSFILES += fs-kernel_mod-kern_misc.lst +PARTMAPFILES += partmap-kernel_mod-kern_misc.lst + +cmd-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_mm.d + +CLEANFILES += cmd-kernel_mod-kern_mm.lst fs-kernel_mod-kern_mm.lst partmap-kernel_mod-kern_mm.lst +COMMANDFILES += cmd-kernel_mod-kern_mm.lst +FSFILES += fs-kernel_mod-kern_mm.lst +PARTMAPFILES += partmap-kernel_mod-kern_mm.lst + +cmd-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_loader.d + +CLEANFILES += cmd-kernel_mod-kern_loader.lst fs-kernel_mod-kern_loader.lst partmap-kernel_mod-kern_loader.lst +COMMANDFILES += cmd-kernel_mod-kern_loader.lst +FSFILES += fs-kernel_mod-kern_loader.lst +PARTMAPFILES += partmap-kernel_mod-kern_loader.lst + +cmd-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_rescue.d + +CLEANFILES += cmd-kernel_mod-kern_rescue.lst fs-kernel_mod-kern_rescue.lst partmap-kernel_mod-kern_rescue.lst +COMMANDFILES += cmd-kernel_mod-kern_rescue.lst +FSFILES += fs-kernel_mod-kern_rescue.lst +PARTMAPFILES += partmap-kernel_mod-kern_rescue.lst + +cmd-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_term.d + +CLEANFILES += cmd-kernel_mod-kern_term.lst fs-kernel_mod-kern_term.lst partmap-kernel_mod-kern_term.lst +COMMANDFILES += cmd-kernel_mod-kern_term.lst +FSFILES += fs-kernel_mod-kern_term.lst +PARTMAPFILES += partmap-kernel_mod-kern_term.lst + +cmd-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_dl.o: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_dl.d + +CLEANFILES += cmd-kernel_mod-kern_i386_dl.lst fs-kernel_mod-kern_i386_dl.lst partmap-kernel_mod-kern_i386_dl.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_dl.lst +FSFILES += fs-kernel_mod-kern_i386_dl.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_dl.lst + +cmd-kernel_mod-kern_i386_dl.lst: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_dl.lst: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_dl.lst: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_efi_init.o: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_efi_init.d + +CLEANFILES += cmd-kernel_mod-kern_i386_efi_init.lst fs-kernel_mod-kern_i386_efi_init.lst partmap-kernel_mod-kern_i386_efi_init.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_efi_init.lst +FSFILES += fs-kernel_mod-kern_i386_efi_init.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_init.lst + +cmd-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_parser.d + +CLEANFILES += cmd-kernel_mod-kern_parser.lst fs-kernel_mod-kern_parser.lst partmap-kernel_mod-kern_parser.lst +COMMANDFILES += cmd-kernel_mod-kern_parser.lst +FSFILES += fs-kernel_mod-kern_parser.lst +PARTMAPFILES += partmap-kernel_mod-kern_parser.lst + +cmd-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_partition.d + +CLEANFILES += cmd-kernel_mod-kern_partition.lst fs-kernel_mod-kern_partition.lst partmap-kernel_mod-kern_partition.lst +COMMANDFILES += cmd-kernel_mod-kern_partition.lst +FSFILES += fs-kernel_mod-kern_partition.lst +PARTMAPFILES += partmap-kernel_mod-kern_partition.lst + +cmd-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_env.d + +CLEANFILES += cmd-kernel_mod-kern_env.lst fs-kernel_mod-kern_env.lst partmap-kernel_mod-kern_env.lst +COMMANDFILES += cmd-kernel_mod-kern_env.lst +FSFILES += fs-kernel_mod-kern_env.lst +PARTMAPFILES += partmap-kernel_mod-kern_env.lst + +cmd-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-symlist.d + +CLEANFILES += cmd-kernel_mod-symlist.lst fs-kernel_mod-symlist.lst partmap-kernel_mod-symlist.lst +COMMANDFILES += cmd-kernel_mod-symlist.lst +FSFILES += fs-kernel_mod-symlist.lst +PARTMAPFILES += partmap-kernel_mod-symlist.lst + +cmd-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_efi.o: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_efi.d + +CLEANFILES += cmd-kernel_mod-kern_efi_efi.lst fs-kernel_mod-kern_efi_efi.lst partmap-kernel_mod-kern_efi_efi.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_efi.lst +FSFILES += fs-kernel_mod-kern_efi_efi.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_efi.lst + +cmd-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_init.o: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_init.d + +CLEANFILES += cmd-kernel_mod-kern_efi_init.lst fs-kernel_mod-kern_efi_init.lst partmap-kernel_mod-kern_efi_init.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_init.lst +FSFILES += fs-kernel_mod-kern_efi_init.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_init.lst + +cmd-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_mm.o: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_mm.d + +CLEANFILES += cmd-kernel_mod-kern_efi_mm.lst fs-kernel_mod-kern_efi_mm.lst partmap-kernel_mod-kern_efi_mm.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_mm.lst +FSFILES += fs-kernel_mod-kern_efi_mm.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_mm.lst + +cmd-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-term_efi_console.o: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-term_efi_console.d + +CLEANFILES += cmd-kernel_mod-term_efi_console.lst fs-kernel_mod-term_efi_console.lst partmap-kernel_mod-term_efi_console.lst +COMMANDFILES += cmd-kernel_mod-term_efi_console.lst +FSFILES += fs-kernel_mod-term_efi_console.lst +PARTMAPFILES += partmap-kernel_mod-term_efi_console.lst + +cmd-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-disk_efi_efidisk.o: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-disk_efi_efidisk.d + +CLEANFILES += cmd-kernel_mod-disk_efi_efidisk.lst fs-kernel_mod-disk_efi_efidisk.lst partmap-kernel_mod-disk_efi_efidisk.lst +COMMANDFILES += cmd-kernel_mod-disk_efi_efidisk.lst +FSFILES += fs-kernel_mod-disk_efi_efidisk.lst +PARTMAPFILES += partmap-kernel_mod-disk_efi_efidisk.lst + +cmd-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_time.d + +CLEANFILES += cmd-kernel_mod-kern_time.lst fs-kernel_mod-kern_time.lst partmap-kernel_mod-kern_time.lst +COMMANDFILES += cmd-kernel_mod-kern_time.lst +FSFILES += fs-kernel_mod-kern_time.lst +PARTMAPFILES += partmap-kernel_mod-kern_time.lst + +cmd-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_tsc.d + +CLEANFILES += cmd-kernel_mod-kern_i386_tsc.lst fs-kernel_mod-kern_i386_tsc.lst partmap-kernel_mod-kern_i386_tsc.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_tsc.lst +FSFILES += fs-kernel_mod-kern_i386_tsc.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_tsc.lst + +cmd-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_pit.d + +CLEANFILES += cmd-kernel_mod-kern_i386_pit.lst fs-kernel_mod-kern_i386_pit.lst partmap-kernel_mod-kern_i386_pit.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_pit.lst +FSFILES += fs-kernel_mod-kern_i386_pit.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_pit.lst + +cmd-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_generic_rtc_get_time_ms.d + +CLEANFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst fs-kernel_mod-kern_generic_rtc_get_time_ms.lst partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst +COMMANDFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst +FSFILES += fs-kernel_mod-kern_generic_rtc_get_time_ms.lst +PARTMAPFILES += partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst + +cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_generic_millisleep.d + +CLEANFILES += cmd-kernel_mod-kern_generic_millisleep.lst fs-kernel_mod-kern_generic_millisleep.lst partmap-kernel_mod-kern_generic_millisleep.lst +COMMANDFILES += cmd-kernel_mod-kern_generic_millisleep.lst +FSFILES += fs-kernel_mod-kern_generic_millisleep.lst +PARTMAPFILES += partmap-kernel_mod-kern_generic_millisleep.lst + +cmd-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + efi/efi.h efi/time.h efi/disk.h +kernel_mod_CFLAGS = $(COMMON_CFLAGS) +kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) +kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_i386_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_i386_setjmp.o: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_i386_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_i386_setjmp.lst fs-normal_mod-normal_i386_setjmp.lst partmap-normal_mod-normal_i386_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_i386_setjmp.lst +FSFILES += fs-normal_mod-normal_i386_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_i386_setjmp.lst + +cmd-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/efi/chainloader.c +CLEANFILES += _chain.mod mod-_chain.o mod-_chain.c pre-_chain.o _chain_mod-loader_efi_chainloader.o und-_chain.lst +ifneq ($(_chain_mod_EXPORTS),no) +CLEANFILES += def-_chain.lst +DEFSYMFILES += def-_chain.lst +endif +MOSTLYCLEANFILES += _chain_mod-loader_efi_chainloader.d +UNDSYMFILES += und-_chain.lst + +_chain.mod: pre-_chain.o mod-_chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_chain.o mod-_chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_chain.o: $(_chain_mod_DEPENDENCIES) _chain_mod-loader_efi_chainloader.o + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _chain_mod-loader_efi_chainloader.o + +mod-_chain.o: mod-_chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -c -o $@ $< + +mod-_chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_chain_mod_EXPORTS),no) +def-_chain.lst: pre-_chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _chain/' > $@ +endif + +und-_chain.lst: pre-_chain.o + echo '_chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_chain_mod-loader_efi_chainloader.o: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -MD -c -o $@ $< +-include _chain_mod-loader_efi_chainloader.d + +CLEANFILES += cmd-_chain_mod-loader_efi_chainloader.lst fs-_chain_mod-loader_efi_chainloader.lst partmap-_chain_mod-loader_efi_chainloader.lst +COMMANDFILES += cmd-_chain_mod-loader_efi_chainloader.lst +FSFILES += fs-_chain_mod-loader_efi_chainloader.lst +PARTMAPFILES += partmap-_chain_mod-loader_efi_chainloader.lst + +cmd-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _chain > $@ || (rm -f $@; exit 1) + +fs-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _chain > $@ || (rm -f $@; exit 1) + +partmap-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _chain > $@ || (rm -f $@; exit 1) + + +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/efi/chainloader_normal.c +CLEANFILES += chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_efi_chainloader_normal.o und-chain.lst +ifneq ($(chain_mod_EXPORTS),no) +CLEANFILES += def-chain.lst +DEFSYMFILES += def-chain.lst +endif +MOSTLYCLEANFILES += chain_mod-loader_efi_chainloader_normal.d +UNDSYMFILES += und-chain.lst + +chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_efi_chainloader_normal.o + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_efi_chainloader_normal.o + +mod-chain.o: mod-chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $< + +mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(chain_mod_EXPORTS),no) +def-chain.lst: pre-chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@ +endif + +und-chain.lst: pre-chain.o + echo 'chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +chain_mod-loader_efi_chainloader_normal.o: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $< +-include chain_mod-loader_efi_chainloader_normal.d + +CLEANFILES += cmd-chain_mod-loader_efi_chainloader_normal.lst fs-chain_mod-loader_efi_chainloader_normal.lst partmap-chain_mod-loader_efi_chainloader_normal.lst +COMMANDFILES += cmd-chain_mod-loader_efi_chainloader_normal.lst +FSFILES += fs-chain_mod-loader_efi_chainloader_normal.lst +PARTMAPFILES += partmap-chain_mod-loader_efi_chainloader_normal.lst + +cmd-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1) + +fs-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1) + +partmap-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1) + + +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For appleldr.mod. +appleldr_mod_SOURCES = loader/efi/appleloader.c +CLEANFILES += appleldr.mod mod-appleldr.o mod-appleldr.c pre-appleldr.o appleldr_mod-loader_efi_appleloader.o und-appleldr.lst +ifneq ($(appleldr_mod_EXPORTS),no) +CLEANFILES += def-appleldr.lst +DEFSYMFILES += def-appleldr.lst +endif +MOSTLYCLEANFILES += appleldr_mod-loader_efi_appleloader.d +UNDSYMFILES += und-appleldr.lst + +appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-appleldr.o mod-appleldr.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-appleldr.o: $(appleldr_mod_DEPENDENCIES) appleldr_mod-loader_efi_appleloader.o + -rm -f $@ + $(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ appleldr_mod-loader_efi_appleloader.o + +mod-appleldr.o: mod-appleldr.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -c -o $@ $< + +mod-appleldr.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'appleldr' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(appleldr_mod_EXPORTS),no) +def-appleldr.lst: pre-appleldr.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@ +endif + +und-appleldr.lst: pre-appleldr.o + echo 'appleldr' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +appleldr_mod-loader_efi_appleloader.o: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -MD -c -o $@ $< +-include appleldr_mod-loader_efi_appleloader.d + +CLEANFILES += cmd-appleldr_mod-loader_efi_appleloader.lst fs-appleldr_mod-loader_efi_appleloader.lst partmap-appleldr_mod-loader_efi_appleloader.lst +COMMANDFILES += cmd-appleldr_mod-loader_efi_appleloader.lst +FSFILES += fs-appleldr_mod-loader_efi_appleloader.lst +PARTMAPFILES += partmap-appleldr_mod-loader_efi_appleloader.lst + +cmd-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh appleldr > $@ || (rm -f $@; exit 1) + +fs-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh appleldr > $@ || (rm -f $@; exit 1) + +partmap-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh appleldr > $@ || (rm -f $@; exit 1) + + +appleldr_mod_CFLAGS = $(COMMON_CFLAGS) +appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/efi/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_i386_efi_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_i386_efi_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_i386_efi_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_i386_efi_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_i386_efi_linux.o: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_i386_efi_linux.d + +CLEANFILES += cmd-_linux_mod-loader_i386_efi_linux.lst fs-_linux_mod-loader_i386_efi_linux.lst partmap-_linux_mod-loader_i386_efi_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_i386_efi_linux.lst +FSFILES += fs-_linux_mod-loader_i386_efi_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_i386_efi_linux.lst + +cmd-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_linux_normal.o: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_linux_normal.lst fs-linux_mod-loader_linux_normal.lst partmap-linux_mod-loader_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_linux_normal.lst +FSFILES += fs-linux_mod-loader_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_linux_normal.lst + +cmd-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst +PARTMAPFILES += partmap-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + +partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst +PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + +partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/efi/datetime.c +CLEANFILES += datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o und-datetime.lst +ifneq ($(datetime_mod_EXPORTS),no) +CLEANFILES += def-datetime.lst +DEFSYMFILES += def-datetime.lst +endif +MOSTLYCLEANFILES += datetime_mod-lib_datetime.d datetime_mod-lib_efi_datetime.d +UNDSYMFILES += und-datetime.lst + +datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o + +mod-datetime.o: mod-datetime.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $< + +mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datetime_mod_EXPORTS),no) +def-datetime.lst: pre-datetime.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@ +endif + +und-datetime.lst: pre-datetime.o + echo 'datetime' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datetime_mod-lib_datetime.o: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_datetime.lst fs-datetime_mod-lib_datetime.lst partmap-datetime_mod-lib_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_datetime.lst +FSFILES += fs-datetime_mod-lib_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_datetime.lst + +cmd-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod-lib_efi_datetime.o: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_efi_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_efi_datetime.lst fs-datetime_mod-lib_efi_datetime.lst partmap-datetime_mod-lib_efi_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_efi_datetime.lst +FSFILES += fs-datetime_mod-lib_efi_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_efi_datetime.lst + +cmd-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +CLEANFILES += date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst +ifneq ($(date_mod_EXPORTS),no) +CLEANFILES += def-date.lst +DEFSYMFILES += def-date.lst +endif +MOSTLYCLEANFILES += date_mod-commands_date.d +UNDSYMFILES += und-date.lst + +date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o + +mod-date.o: mod-date.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $< + +mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(date_mod_EXPORTS),no) +def-date.lst: pre-date.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@ +endif + +und-date.lst: pre-date.o + echo 'date' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $< +-include date_mod-commands_date.d + +CLEANFILES += cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst +COMMANDFILES += cmd-date_mod-commands_date.lst +FSFILES += fs-date_mod-commands_date.lst +PARTMAPFILES += partmap-date_mod-commands_date.lst + +cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1) + +fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1) + +partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1) + + +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +CLEANFILES += datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst +ifneq ($(datehook_mod_EXPORTS),no) +CLEANFILES += def-datehook.lst +DEFSYMFILES += def-datehook.lst +endif +MOSTLYCLEANFILES += datehook_mod-hook_datehook.d +UNDSYMFILES += und-datehook.lst + +datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o + +mod-datehook.o: mod-datehook.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $< + +mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datehook_mod_EXPORTS),no) +def-datehook.lst: pre-datehook.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@ +endif + +und-datehook.lst: pre-datehook.o + echo 'datehook' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) + $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $< +-include datehook_mod-hook_datehook.d + +CLEANFILES += cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst +COMMANDFILES += cmd-datehook_mod-hook_datehook.lst +FSFILES += fs-datehook_mod-hook_datehook.lst +PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst + +cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1) + +fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1) + +partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1) + + +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk new file mode 100644 index 0000000..3814abb --- /dev/null +++ b/conf/i386-efi.rmk @@ -0,0 +1,195 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -m32 +COMMON_LDFLAGS = -melf_i386 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Utilities. +bin_UTILITIES = grub-mkimage +sbin_UTILITIES = grub-mkdevicemap +#ifeq ($(enable_grub_emu), yes) +#sbin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \ + util/resolve.c +util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-setup. +#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ +# util/misc.c util/getroot.c kern/device.c kern/disk.c \ +# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c \ +# fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/hexdump.c lib/hexdump.c \ + commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/context.c normal/main.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/efi/grub-install.in + +# Modules. +pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ + _linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod + +# For kernel.mod. +kernel_mod_EXPORTS = no +kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ + kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ + term/efi/console.c disk/efi/efidisk.c \ + kern/time.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c +kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + efi/efi.h efi/time.h efi/disk.h +kernel_mod_CFLAGS = $(COMMON_CFLAGS) +kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) +kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/efi/chainloader.c +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/efi/chainloader_normal.c +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For appleldr.mod. +appleldr_mod_SOURCES = loader/efi/appleloader.c +appleldr_mod_CFLAGS = $(COMMON_CFLAGS) +appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/efi/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/efi/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-ieee1275.mk b/conf/i386-ieee1275.mk new file mode 100644 index 0000000..504a185 --- /dev/null +++ b/conf/i386-ieee1275.mk @@ -0,0 +1,2012 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin +COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 +COMMON_LDFLAGS = -nostdlib -static -lgcc + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_PROGRAMS = kernel.elf + +# For kernel.elf. +kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \ + kern/ieee1275/init.c \ + kern/ieee1275/mmap.c \ + kern/ieee1275/cmain.c kern/ieee1275/openfw.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/parser.c kern/partition.c \ + kern/env.c \ + kern/time.c \ + kern/generic/millisleep.c \ + kern/ieee1275/ieee1275.c \ + term/ieee1275/ofconsole.c \ + disk/ieee1275/ofdisk.c \ + symlist.c +CLEANFILES += kernel.elf kernel_elf-kern_i386_ieee1275_startup.o kernel_elf-kern_i386_ieee1275_init.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_time.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-symlist.o +MOSTLYCLEANFILES += kernel_elf-kern_i386_ieee1275_startup.d kernel_elf-kern_i386_ieee1275_init.d kernel_elf-kern_ieee1275_init.d kernel_elf-kern_ieee1275_mmap.d kernel_elf-kern_ieee1275_cmain.d kernel_elf-kern_ieee1275_openfw.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_i386_dl.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_env.d kernel_elf-kern_time.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_ieee1275_ieee1275.d kernel_elf-term_ieee1275_ofconsole.d kernel_elf-disk_ieee1275_ofdisk.d kernel_elf-symlist.d + +kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_i386_ieee1275_startup.o kernel_elf-kern_i386_ieee1275_init.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_time.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-symlist.o + $(TARGET_CC) -o $@ kernel_elf-kern_i386_ieee1275_startup.o kernel_elf-kern_i386_ieee1275_init.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_i386_dl.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_time.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-symlist.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) + +kernel_elf-kern_i386_ieee1275_startup.o: kern/i386/ieee1275/startup.S $(kern/i386/ieee1275/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/ieee1275 -I$(srcdir)/kern/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_ieee1275_startup.d + +kernel_elf-kern_i386_ieee1275_init.o: kern/i386/ieee1275/init.c $(kern/i386/ieee1275/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/ieee1275 -I$(srcdir)/kern/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_ieee1275_init.d + +kernel_elf-kern_ieee1275_init.o: kern/ieee1275/init.c $(kern/ieee1275/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_init.d + +kernel_elf-kern_ieee1275_mmap.o: kern/ieee1275/mmap.c $(kern/ieee1275/mmap.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_mmap.d + +kernel_elf-kern_ieee1275_cmain.o: kern/ieee1275/cmain.c $(kern/ieee1275/cmain.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_cmain.d + +kernel_elf-kern_ieee1275_openfw.o: kern/ieee1275/openfw.c $(kern/ieee1275/openfw.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_openfw.d + +kernel_elf-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_main.d + +kernel_elf-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_device.d + +kernel_elf-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_disk.d + +kernel_elf-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_dl.d + +kernel_elf-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_file.d + +kernel_elf-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_fs.d + +kernel_elf-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_err.d + +kernel_elf-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_misc.d + +kernel_elf-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_mm.d + +kernel_elf-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_loader.d + +kernel_elf-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_rescue.d + +kernel_elf-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_term.d + +kernel_elf-kern_i386_dl.o: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_i386_dl.d + +kernel_elf-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_parser.d + +kernel_elf-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_partition.d + +kernel_elf-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_env.d + +kernel_elf-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_time.d + +kernel_elf-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_millisleep.d + +kernel_elf-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_ieee1275.d + +kernel_elf-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_ieee1275_ofconsole.d + +kernel_elf-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-disk_ieee1275_ofdisk.d + +kernel_elf-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-symlist.d + +kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c +CLEANFILES += grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o +MOSTLYCLEANFILES += grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_misc.d + +grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o + $(CC) -o $@ grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS) + +grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_grub_mkdevicemap.d + +grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_misc.d + + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/host.c disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + fs/fshelp.c \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/menu_text.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c +CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o +MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_halt.d grub_emu-commands_reboot.d grub_emu-commands_i386_cpuid.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_menu_text.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-normal_color.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_i386_pc_misc.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d + +grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o + $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_menu_text.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS) + +grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_boot.d + +grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cat.d + +grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cmp.d + +grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_configfile.d + +grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_echo.d + +grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_help.d + +grub_emu-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_terminal.d + +grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_ls.d + +grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_test.d + +grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_search.d + +grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_blocklist.d + +grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_hexdump.d + +grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-lib_hexdump.d + +grub_emu-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_halt.d + +grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_reboot.d + +grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) + $(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_i386_cpuid.d + +grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_host.d + +grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_loopback.d + +grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_affs.d + +grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_cpio.d + +grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fat.d + +grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ext2.d + +grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfs.d + +grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfsplus.d + +grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_iso9660.d + +grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_udf.d + +grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_jfs.d + +grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_minix.d + +grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfs.d + +grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfscomp.d + +grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_reiserfs.d + +grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_sfs.d + +grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ufs.d + +grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_xfs.d + +grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_afs.d + +grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_tar.d + +grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fshelp.d + +grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-io_gzio.d + +grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_device.d + +grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_disk.d + +grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_dl.d + +grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_elf.d + +grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_env.d + +grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_err.d + +grub_emu-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_execute.d + +grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_file.d + +grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_fs.d + +grub_emu-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_lexer.d + +grub_emu-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_loader.d + +grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_main.d + +grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_misc.d + +grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_parser.d + +grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_script_tab.d + +grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_partition.d + +grub_emu-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_rescue.d + +grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_term.d + +grub_emu-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_arg.d + +grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_cmdline.d + +grub_emu-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_command.d + +grub_emu-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_function.d + +grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_completion.d + +grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_main.d + +grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_text.d + +grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu.d + +grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_entry.d + +grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_viewer.d + +grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_misc.d + +grub_emu-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_script.d + +grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_color.d + +grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_amiga.d + +grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_apple.d + +grub_emu-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_pc.d + +grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_sun.d + +grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_acorn.d + +grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_gpt.d + +grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_console.d + +grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostfs.d + +grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_grub_emu.d + +grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_misc.d + +grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostdisk.d + +grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_getroot.d + +grub_emu-util_i386_pc_misc.o: util/i386/pc/misc.c $(util/i386/pc/misc.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_i386_pc_misc.d + +grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid.d + +grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid5_recover.d + +grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid6_recover.d + +grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_mdraid_linux.d + +grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_dmraid_nvidia.d + +grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_lvm.d + +grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_emu_init.d + + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/ieee1275/grub-install.in +CLEANFILES += grub-install + +grub-install: util/ieee1275/grub-install.in $(util/ieee1275/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/ieee1275/grub-install.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod \ + multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \ + _linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ + date.mod datehook.mod lsmmap.mod + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_i386_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_i386_setjmp.o: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_i386_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_i386_setjmp.lst fs-normal_mod-normal_i386_setjmp.lst partmap-normal_mod-normal_i386_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_i386_setjmp.lst +FSFILES += fs-normal_mod-normal_i386_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_i386_setjmp.lst + +cmd-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst +ifneq ($(_multiboot_mod_EXPORTS),no) +CLEANFILES += def-_multiboot.lst +DEFSYMFILES += def-_multiboot.lst +endif +MOSTLYCLEANFILES += _multiboot_mod-loader_ieee1275_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d +UNDSYMFILES += und-_multiboot.lst + +_multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_multiboot.o mod-_multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + +mod-_multiboot.o: mod-_multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $< + +mod-_multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_multiboot_mod_EXPORTS),no) +def-_multiboot.lst: pre-_multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _multiboot/' > $@ +endif + +und-_multiboot.lst: pre-_multiboot.o + echo '_multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_multiboot_mod-loader_ieee1275_multiboot2.o: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_ieee1275_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst fs-_multiboot_mod-loader_ieee1275_multiboot2.lst partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_ieee1275_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst + +cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot2.lst fs-_multiboot_mod-loader_multiboot2.lst partmap-_multiboot_mod-loader_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot2.lst + +cmd-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot_loader.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst fs-_multiboot_mod-loader_multiboot_loader.lst partmap-_multiboot_mod-loader_multiboot_loader.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst +FSFILES += fs-_multiboot_mod-loader_multiboot_loader.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot_loader.lst + +cmd-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +CLEANFILES += multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_multiboot_loader_normal.o und-multiboot.lst +ifneq ($(multiboot_mod_EXPORTS),no) +CLEANFILES += def-multiboot.lst +DEFSYMFILES += def-multiboot.lst +endif +MOSTLYCLEANFILES += multiboot_mod-loader_multiboot_loader_normal.d +UNDSYMFILES += und-multiboot.lst + +multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_multiboot_loader_normal.o + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_multiboot_loader_normal.o + +mod-multiboot.o: mod-multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(multiboot_mod_EXPORTS),no) +def-multiboot.lst: pre-multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@ +endif + +und-multiboot.lst: pre-multiboot.o + echo 'multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +multiboot_mod-loader_multiboot_loader_normal.o: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include multiboot_mod-loader_multiboot_loader_normal.d + +CLEANFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst fs-multiboot_mod-loader_multiboot_loader_normal.lst partmap-multiboot_mod-loader_multiboot_loader_normal.lst +COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst +FSFILES += fs-multiboot_mod-loader_multiboot_loader_normal.lst +PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader_normal.lst + +cmd-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1) + +fs-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1) + +partmap-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1) + + +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +CLEANFILES += aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst +ifneq ($(aout_mod_EXPORTS),no) +CLEANFILES += def-aout.lst +DEFSYMFILES += def-aout.lst +endif +MOSTLYCLEANFILES += aout_mod-loader_aout.d +UNDSYMFILES += und-aout.lst + +aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o + +mod-aout.o: mod-aout.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $< + +mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(aout_mod_EXPORTS),no) +def-aout.lst: pre-aout.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@ +endif + +und-aout.lst: pre-aout.o + echo 'aout' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $< +-include aout_mod-loader_aout.d + +CLEANFILES += cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst +COMMANDFILES += cmd-aout_mod-loader_aout.lst +FSFILES += fs-aout_mod-loader_aout.lst +PARTMAPFILES += partmap-aout_mod-loader_aout.lst + +cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1) + +fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1) + +partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1) + + +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +CLEANFILES += suspend.mod mod-suspend.o mod-suspend.c pre-suspend.o suspend_mod-commands_ieee1275_suspend.o und-suspend.lst +ifneq ($(suspend_mod_EXPORTS),no) +CLEANFILES += def-suspend.lst +DEFSYMFILES += def-suspend.lst +endif +MOSTLYCLEANFILES += suspend_mod-commands_ieee1275_suspend.d +UNDSYMFILES += und-suspend.lst + +suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-suspend.o mod-suspend.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-suspend.o: $(suspend_mod_DEPENDENCIES) suspend_mod-commands_ieee1275_suspend.o + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ suspend_mod-commands_ieee1275_suspend.o + +mod-suspend.o: mod-suspend.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -c -o $@ $< + +mod-suspend.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'suspend' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(suspend_mod_EXPORTS),no) +def-suspend.lst: pre-suspend.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 suspend/' > $@ +endif + +und-suspend.lst: pre-suspend.o + echo 'suspend' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +suspend_mod-commands_ieee1275_suspend.o: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -MD -c -o $@ $< +-include suspend_mod-commands_ieee1275_suspend.d + +CLEANFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst fs-suspend_mod-commands_ieee1275_suspend.lst partmap-suspend_mod-commands_ieee1275_suspend.lst +COMMANDFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst +FSFILES += fs-suspend_mod-commands_ieee1275_suspend.lst +PARTMAPFILES += partmap-suspend_mod-commands_ieee1275_suspend.lst + +cmd-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh suspend > $@ || (rm -f $@; exit 1) + +fs-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh suspend > $@ || (rm -f $@; exit 1) + +partmap-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh suspend > $@ || (rm -f $@; exit 1) + + +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +CLEANFILES += serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst +ifneq ($(serial_mod_EXPORTS),no) +CLEANFILES += def-serial.lst +DEFSYMFILES += def-serial.lst +endif +MOSTLYCLEANFILES += serial_mod-term_i386_pc_serial.d +UNDSYMFILES += und-serial.lst + +serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o + +mod-serial.o: mod-serial.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $< + +mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(serial_mod_EXPORTS),no) +def-serial.lst: pre-serial.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@ +endif + +und-serial.lst: pre-serial.o + echo 'serial' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $< +-include serial_mod-term_i386_pc_serial.d + +CLEANFILES += cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst +COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst +FSFILES += fs-serial_mod-term_i386_pc_serial.lst +PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst + +cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1) + +fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1) + +partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1) + + +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/ieee1275/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_i386_ieee1275_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_i386_ieee1275_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_i386_ieee1275_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_i386_ieee1275_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_i386_ieee1275_linux.o: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_i386_ieee1275_linux.d + +CLEANFILES += cmd-_linux_mod-loader_i386_ieee1275_linux.lst fs-_linux_mod-loader_i386_ieee1275_linux.lst partmap-_linux_mod-loader_i386_ieee1275_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_i386_ieee1275_linux.lst +FSFILES += fs-_linux_mod-loader_i386_ieee1275_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_i386_ieee1275_linux.lst + +cmd-_linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_i386_ieee1275_linux.lst: loader/i386/ieee1275/linux.c $(loader/i386/ieee1275/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/ieee1275 -I$(srcdir)/loader/i386/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_linux_normal.o: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_linux_normal.lst fs-linux_mod-loader_linux_normal.lst partmap-linux_mod-loader_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_linux_normal.lst +FSFILES += fs-linux_mod-loader_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_linux_normal.lst + +cmd-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For nand.mod. +nand_mod_SOURCES = disk/ieee1275/nand.c +CLEANFILES += nand.mod mod-nand.o mod-nand.c pre-nand.o nand_mod-disk_ieee1275_nand.o und-nand.lst +ifneq ($(nand_mod_EXPORTS),no) +CLEANFILES += def-nand.lst +DEFSYMFILES += def-nand.lst +endif +MOSTLYCLEANFILES += nand_mod-disk_ieee1275_nand.d +UNDSYMFILES += und-nand.lst + +nand.mod: pre-nand.o mod-nand.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(nand_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-nand.o mod-nand.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-nand.o: $(nand_mod_DEPENDENCIES) nand_mod-disk_ieee1275_nand.o + -rm -f $@ + $(TARGET_CC) $(nand_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ nand_mod-disk_ieee1275_nand.o + +mod-nand.o: mod-nand.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -c -o $@ $< + +mod-nand.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'nand' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(nand_mod_EXPORTS),no) +def-nand.lst: pre-nand.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 nand/' > $@ +endif + +und-nand.lst: pre-nand.o + echo 'nand' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +nand_mod-disk_ieee1275_nand.o: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -MD -c -o $@ $< +-include nand_mod-disk_ieee1275_nand.d + +CLEANFILES += cmd-nand_mod-disk_ieee1275_nand.lst fs-nand_mod-disk_ieee1275_nand.lst partmap-nand_mod-disk_ieee1275_nand.lst +COMMANDFILES += cmd-nand_mod-disk_ieee1275_nand.lst +FSFILES += fs-nand_mod-disk_ieee1275_nand.lst +PARTMAPFILES += partmap-nand_mod-disk_ieee1275_nand.lst + +cmd-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh nand > $@ || (rm -f $@; exit 1) + +fs-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh nand > $@ || (rm -f $@; exit 1) + +partmap-nand_mod-disk_ieee1275_nand.lst: disk/ieee1275/nand.c $(disk/ieee1275/nand.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(nand_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh nand > $@ || (rm -f $@; exit 1) + + +nand_mod_CFLAGS = $(COMMON_CFLAGS) +nand_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst +PARTMAPFILES += partmap-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + +partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst +PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + +partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +CLEANFILES += datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst +ifneq ($(datetime_mod_EXPORTS),no) +CLEANFILES += def-datetime.lst +DEFSYMFILES += def-datetime.lst +endif +MOSTLYCLEANFILES += datetime_mod-lib_datetime.d datetime_mod-lib_i386_datetime.d +UNDSYMFILES += und-datetime.lst + +datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + +mod-datetime.o: mod-datetime.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $< + +mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datetime_mod_EXPORTS),no) +def-datetime.lst: pre-datetime.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@ +endif + +und-datetime.lst: pre-datetime.o + echo 'datetime' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datetime_mod-lib_datetime.o: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_datetime.lst fs-datetime_mod-lib_datetime.lst partmap-datetime_mod-lib_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_datetime.lst +FSFILES += fs-datetime_mod-lib_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_datetime.lst + +cmd-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_i386_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst +FSFILES += fs-datetime_mod-lib_i386_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst + +cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +CLEANFILES += date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst +ifneq ($(date_mod_EXPORTS),no) +CLEANFILES += def-date.lst +DEFSYMFILES += def-date.lst +endif +MOSTLYCLEANFILES += date_mod-commands_date.d +UNDSYMFILES += und-date.lst + +date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o + +mod-date.o: mod-date.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $< + +mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(date_mod_EXPORTS),no) +def-date.lst: pre-date.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@ +endif + +und-date.lst: pre-date.o + echo 'date' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $< +-include date_mod-commands_date.d + +CLEANFILES += cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst +COMMANDFILES += cmd-date_mod-commands_date.lst +FSFILES += fs-date_mod-commands_date.lst +PARTMAPFILES += partmap-date_mod-commands_date.lst + +cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1) + +fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1) + +partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1) + + +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +CLEANFILES += datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst +ifneq ($(datehook_mod_EXPORTS),no) +CLEANFILES += def-datehook.lst +DEFSYMFILES += def-datehook.lst +endif +MOSTLYCLEANFILES += datehook_mod-hook_datehook.d +UNDSYMFILES += und-datehook.lst + +datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o + +mod-datehook.o: mod-datehook.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $< + +mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datehook_mod_EXPORTS),no) +def-datehook.lst: pre-datehook.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@ +endif + +und-datehook.lst: pre-datehook.o + echo 'datehook' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) + $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $< +-include datehook_mod-hook_datehook.d + +CLEANFILES += cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst +COMMANDFILES += cmd-datehook_mod-hook_datehook.lst +FSFILES += fs-datehook_mod-hook_datehook.lst +PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst + +cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1) + +fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1) + +partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1) + + +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +CLEANFILES += lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst +ifneq ($(lsmmap_mod_EXPORTS),no) +CLEANFILES += def-lsmmap.lst +DEFSYMFILES += def-lsmmap.lst +endif +MOSTLYCLEANFILES += lsmmap_mod-commands_lsmmap.d +UNDSYMFILES += und-lsmmap.lst + +lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o + +mod-lsmmap.o: mod-lsmmap.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $< + +mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lsmmap_mod_EXPORTS),no) +def-lsmmap.lst: pre-lsmmap.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@ +endif + +und-lsmmap.lst: pre-lsmmap.o + echo 'lsmmap' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $< +-include lsmmap_mod-commands_lsmmap.d + +CLEANFILES += cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst +COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst +FSFILES += fs-lsmmap_mod-commands_lsmmap.lst +PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst + +cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1) + +fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1) + +partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1) + + +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk new file mode 100644 index 0000000..903113e --- /dev/null +++ b/conf/i386-ieee1275.rmk @@ -0,0 +1,214 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin +COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 +COMMON_LDFLAGS = -nostdlib -static -lgcc + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_PROGRAMS = kernel.elf + +# For kernel.elf. +kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \ + kern/ieee1275/init.c \ + kern/ieee1275/mmap.c \ + kern/ieee1275/cmain.c kern/ieee1275/openfw.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/i386/dl.c kern/parser.c kern/partition.c \ + kern/env.c \ + kern/time.c \ + kern/generic/millisleep.c \ + kern/ieee1275/ieee1275.c \ + term/ieee1275/ofconsole.c \ + disk/ieee1275/ofdisk.c \ + symlist.c +kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/host.c disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + fs/fshelp.c \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/menu_text.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/ieee1275/grub-install.in + +# Modules. +pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod \ + multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod \ + _linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ + date.mod datehook.mod lsmmap.mod + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/ieee1275/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For nand.mod. +nand_mod_SOURCES = disk/ieee1275/nand.c +nand_mod_CFLAGS = $(COMMON_CFLAGS) +nand_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc-cygwin-img-ld.sc b/conf/i386-pc-cygwin-img-ld.sc new file mode 100644 index 0000000..a41cac7 --- /dev/null +++ b/conf/i386-pc-cygwin-img-ld.sc @@ -0,0 +1,53 @@ +/* Linker script to create grub .img files on Cygwin. */ + +SECTIONS +{ + .text : + { + start = . ; + *(.text) + etext = . ; + } + .data : + { + __data_start__ = . ; + *(.data) + __data_end__ = . ; + } + .rdata : + { + __rdata_start__ = . ; + *(.rdata) + __rdata_end__ = . ; + } + .pdata : + { + *(.pdata) + edata = . ; + } + .bss : + { + __bss_start__ = . ; + *(.bss) + __common_start__ = . ; + *(COMMON) + __bss_end__ = . ; + } + .edata : + { + *(.edata) + end = . ; + } + .stab : + { + *(.stab) + } + .stabstr : + { + *(.stabstr) + } +} + +ASSERT("__rdata_end__"=="edata", ".pdata not empty") +ASSERT("__bss_end__" =="end" , ".edata not empty") + diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk new file mode 100644 index 0000000..72e0957 --- /dev/null +++ b/conf/i386-pc.mk @@ -0,0 +1,3609 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +GRUB_MEMORY_MACHINE_LINK_ADDR = 0x8200 + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img \ + cdboot.img + +# For boot.img. +boot_img_SOURCES = boot/i386/pc/boot.S +CLEANFILES += boot.img boot.exec boot_img-boot_i386_pc_boot.o +MOSTLYCLEANFILES += boot_img-boot_i386_pc_boot.d + +boot.img: boot.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +boot.exec: boot_img-boot_i386_pc_boot.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(boot_img_LDFLAGS) + +boot_img-boot_i386_pc_boot.o: boot/i386/pc/boot.S $(boot/i386/pc/boot.S_DEPENDENCIES) + $(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(boot_img_ASFLAGS) -MD -c -o $@ $< +-include boot_img-boot_i386_pc_boot.d + +boot_img_ASFLAGS = $(COMMON_ASFLAGS) +boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For pxeboot.img +pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S +CLEANFILES += pxeboot.img pxeboot.exec pxeboot_img-boot_i386_pc_pxeboot.o +MOSTLYCLEANFILES += pxeboot_img-boot_i386_pc_pxeboot.d + +pxeboot.img: pxeboot.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +pxeboot.exec: pxeboot_img-boot_i386_pc_pxeboot.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(pxeboot_img_LDFLAGS) + +pxeboot_img-boot_i386_pc_pxeboot.o: boot/i386/pc/pxeboot.S $(boot/i386/pc/pxeboot.S_DEPENDENCIES) + $(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(pxeboot_img_ASFLAGS) -MD -c -o $@ $< +-include pxeboot_img-boot_i386_pc_pxeboot.d + +pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS) +pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For diskboot.img. +diskboot_img_SOURCES = boot/i386/pc/diskboot.S +CLEANFILES += diskboot.img diskboot.exec diskboot_img-boot_i386_pc_diskboot.o +MOSTLYCLEANFILES += diskboot_img-boot_i386_pc_diskboot.d + +diskboot.img: diskboot.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +diskboot.exec: diskboot_img-boot_i386_pc_diskboot.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(diskboot_img_LDFLAGS) + +diskboot_img-boot_i386_pc_diskboot.o: boot/i386/pc/diskboot.S $(boot/i386/pc/diskboot.S_DEPENDENCIES) + $(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(diskboot_img_ASFLAGS) -MD -c -o $@ $< +-include diskboot_img-boot_i386_pc_diskboot.d + +diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) +diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,8000 + +# For lnxboot.img. +lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S +CLEANFILES += lnxboot.img lnxboot.exec lnxboot_img-boot_i386_pc_lnxboot.o +MOSTLYCLEANFILES += lnxboot_img-boot_i386_pc_lnxboot.d + +lnxboot.img: lnxboot.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +lnxboot.exec: lnxboot_img-boot_i386_pc_lnxboot.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(lnxboot_img_LDFLAGS) + +lnxboot_img-boot_i386_pc_lnxboot.o: boot/i386/pc/lnxboot.S $(boot/i386/pc/lnxboot.S_DEPENDENCIES) + $(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(lnxboot_img_ASFLAGS) -MD -c -o $@ $< +-include lnxboot_img-boot_i386_pc_lnxboot.d + +lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS) +lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,6000 + +# For cdboot.img. +cdboot_img_SOURCES = boot/i386/pc/cdboot.S +CLEANFILES += cdboot.img cdboot.exec cdboot_img-boot_i386_pc_cdboot.o +MOSTLYCLEANFILES += cdboot_img-boot_i386_pc_cdboot.d + +cdboot.img: cdboot.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +cdboot.exec: cdboot_img-boot_i386_pc_cdboot.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(cdboot_img_LDFLAGS) + +cdboot_img-boot_i386_pc_cdboot.o: boot/i386/pc/cdboot.S $(boot/i386/pc/cdboot.S_DEPENDENCIES) + $(TARGET_CC) -Iboot/i386/pc -I$(srcdir)/boot/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(cdboot_img_ASFLAGS) -MD -c -o $@ $< +-include cdboot_img-boot_i386_pc_cdboot.d + +cdboot_img_ASFLAGS = $(COMMON_ASFLAGS) +cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For kernel.img. +kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/time.c \ + kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \ + kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/console.c term/i386/vga_common.c \ + symlist.c +CLEANFILES += kernel.img kernel.exec kernel_img-kern_i386_pc_startup.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_loader.o kernel_img-kern_rescue.o kernel_img-kern_term.o kernel_img-kern_time.o kernel_img-kern_i386_dl.o kernel_img-kern_i386_pc_init.o kernel_img-kern_i386_pc_mmap.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_console.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o +MOSTLYCLEANFILES += kernel_img-kern_i386_pc_startup.d kernel_img-kern_main.d kernel_img-kern_device.d kernel_img-kern_disk.d kernel_img-kern_dl.d kernel_img-kern_file.d kernel_img-kern_fs.d kernel_img-kern_err.d kernel_img-kern_misc.d kernel_img-kern_mm.d kernel_img-kern_loader.d kernel_img-kern_rescue.d kernel_img-kern_term.d kernel_img-kern_time.d kernel_img-kern_i386_dl.d kernel_img-kern_i386_pc_init.d kernel_img-kern_i386_pc_mmap.d kernel_img-kern_parser.d kernel_img-kern_partition.d kernel_img-kern_i386_tsc.d kernel_img-kern_i386_pit.d kernel_img-kern_generic_rtc_get_time_ms.d kernel_img-kern_generic_millisleep.d kernel_img-kern_env.d kernel_img-term_i386_pc_console.d kernel_img-term_i386_vga_common.d kernel_img-symlist.d + +kernel.img: kernel.exec + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +kernel.exec: kernel_img-kern_i386_pc_startup.o kernel_img-kern_main.o kernel_img-kern_device.o kernel_img-kern_disk.o kernel_img-kern_dl.o kernel_img-kern_file.o kernel_img-kern_fs.o kernel_img-kern_err.o kernel_img-kern_misc.o kernel_img-kern_mm.o kernel_img-kern_loader.o kernel_img-kern_rescue.o kernel_img-kern_term.o kernel_img-kern_time.o kernel_img-kern_i386_dl.o kernel_img-kern_i386_pc_init.o kernel_img-kern_i386_pc_mmap.o kernel_img-kern_parser.o kernel_img-kern_partition.o kernel_img-kern_i386_tsc.o kernel_img-kern_i386_pit.o kernel_img-kern_generic_rtc_get_time_ms.o kernel_img-kern_generic_millisleep.o kernel_img-kern_env.o kernel_img-term_i386_pc_console.o kernel_img-term_i386_vga_common.o kernel_img-symlist.o + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(kernel_img_LDFLAGS) + +kernel_img-kern_i386_pc_startup.o: kern/i386/pc/startup.S $(kern/i386/pc/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_img_ASFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_pc_startup.d + +kernel_img-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_main.d + +kernel_img-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_device.d + +kernel_img-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_disk.d + +kernel_img-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_dl.d + +kernel_img-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_file.d + +kernel_img-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_fs.d + +kernel_img-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_err.d + +kernel_img-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_misc.d + +kernel_img-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_mm.d + +kernel_img-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_loader.d + +kernel_img-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_rescue.d + +kernel_img-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_term.d + +kernel_img-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_time.d + +kernel_img-kern_i386_dl.o: kern/i386/dl.c $(kern/i386/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_dl.d + +kernel_img-kern_i386_pc_init.o: kern/i386/pc/init.c $(kern/i386/pc/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_pc_init.d + +kernel_img-kern_i386_pc_mmap.o: kern/i386/pc/mmap.c $(kern/i386/pc/mmap.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/pc -I$(srcdir)/kern/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_pc_mmap.d + +kernel_img-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_parser.d + +kernel_img-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_partition.d + +kernel_img-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_tsc.d + +kernel_img-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_i386_pit.d + +kernel_img-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_generic_rtc_get_time_ms.d + +kernel_img-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_generic_millisleep.d + +kernel_img-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-kern_env.d + +kernel_img-term_i386_pc_console.o: term/i386/pc/console.c $(term/i386/pc/console.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-term_i386_pc_console.d + +kernel_img-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-term_i386_vga_common.d + +kernel_img-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_img_CFLAGS) -MD -c -o $@ $< +-include kernel_img-symlist.d + +kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ + machine/kernel.h machine/pxe.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +bin_UTILITIES = grub-mkimage +sbin_UTILITIES = grub-setup grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkimage. +ifeq ($(enable_lzo), yes) +grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ + util/resolve.c +CLEANFILES += grub-mkimage$(EXEEXT) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o +MOSTLYCLEANFILES += grub_mkimage-util_i386_pc_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d + +grub-mkimage: $(grub_mkimage_DEPENDENCIES) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o + $(CC) -o $@ grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o $(LDFLAGS) $(grub_mkimage_LDFLAGS) + +grub_mkimage-util_i386_pc_grub_mkimage.o: util/i386/pc/grub-mkimage.c $(util/i386/pc/grub-mkimage.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_i386_pc_grub_mkimage.d + +grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_misc.d + +grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_resolve.d + +grub_mkimage_LDFLAGS = $(LIBLZO) +else +grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +CLEANFILES += grub-mkimage$(EXEEXT) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o +MOSTLYCLEANFILES += grub_mkimage-util_i386_pc_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d grub_mkimage-lib_LzmaEnc.d grub_mkimage-lib_LzFind.d + +grub-mkimage: $(grub_mkimage_DEPENDENCIES) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o + $(CC) -o $@ grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o $(LDFLAGS) $(grub_mkimage_LDFLAGS) + +grub_mkimage-util_i386_pc_grub_mkimage.o: util/i386/pc/grub-mkimage.c $(util/i386/pc/grub-mkimage.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_i386_pc_grub_mkimage.d + +grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_misc.d + +grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_resolve.d + +grub_mkimage-lib_LzmaEnc.o: lib/LzmaEnc.c $(lib/LzmaEnc.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-lib_LzmaEnc.d + +grub_mkimage-lib_LzFind.o: lib/LzFind.c $(lib/LzFind.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-lib_LzFind.d + +endif +grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR) +util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-setup. +util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h +grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + partmap/pc.c partmap/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c \ + grub_setup_init.c +CLEANFILES += grub-setup$(EXEEXT) grub_setup-util_i386_pc_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_tar.o grub_setup-partmap_pc.o grub_setup-partmap_gpt.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o +MOSTLYCLEANFILES += grub_setup-util_i386_pc_grub_setup.d grub_setup-util_hostdisk.d grub_setup-util_misc.d grub_setup-util_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-kern_parser.d grub_setup-kern_partition.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d grub_setup-fs_fshelp.d grub_setup-fs_affs.d grub_setup-fs_cpio.d grub_setup-fs_ext2.d grub_setup-fs_fat.d grub_setup-fs_hfs.d grub_setup-fs_hfsplus.d grub_setup-fs_iso9660.d grub_setup-fs_udf.d grub_setup-fs_jfs.d grub_setup-fs_minix.d grub_setup-fs_ntfs.d grub_setup-fs_ntfscomp.d grub_setup-fs_reiserfs.d grub_setup-fs_sfs.d grub_setup-fs_ufs.d grub_setup-fs_xfs.d grub_setup-fs_afs.d grub_setup-fs_tar.d grub_setup-partmap_pc.d grub_setup-partmap_gpt.d grub_setup-disk_raid.d grub_setup-disk_mdraid_linux.d grub_setup-disk_lvm.d grub_setup-util_raid.d grub_setup-util_lvm.d grub_setup-grub_setup_init.d + +grub-setup: $(grub_setup_DEPENDENCIES) grub_setup-util_i386_pc_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_tar.o grub_setup-partmap_pc.o grub_setup-partmap_gpt.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o + $(CC) -o $@ grub_setup-util_i386_pc_grub_setup.o grub_setup-util_hostdisk.o grub_setup-util_misc.o grub_setup-util_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-kern_parser.o grub_setup-kern_partition.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o grub_setup-fs_fshelp.o grub_setup-fs_affs.o grub_setup-fs_cpio.o grub_setup-fs_ext2.o grub_setup-fs_fat.o grub_setup-fs_hfs.o grub_setup-fs_hfsplus.o grub_setup-fs_iso9660.o grub_setup-fs_udf.o grub_setup-fs_jfs.o grub_setup-fs_minix.o grub_setup-fs_ntfs.o grub_setup-fs_ntfscomp.o grub_setup-fs_reiserfs.o grub_setup-fs_sfs.o grub_setup-fs_ufs.o grub_setup-fs_xfs.o grub_setup-fs_afs.o grub_setup-fs_tar.o grub_setup-partmap_pc.o grub_setup-partmap_gpt.o grub_setup-disk_raid.o grub_setup-disk_mdraid_linux.o grub_setup-disk_lvm.o grub_setup-util_raid.o grub_setup-util_lvm.o grub_setup-grub_setup_init.o $(LDFLAGS) $(grub_setup_LDFLAGS) + +grub_setup-util_i386_pc_grub_setup.o: util/i386/pc/grub-setup.c $(util/i386/pc/grub-setup.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_i386_pc_grub_setup.d + +grub_setup-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_hostdisk.d + +grub_setup-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_misc.d + +grub_setup-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_getroot.d + +grub_setup-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_device.d + +grub_setup-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_disk.d + +grub_setup-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_err.d + +grub_setup-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_misc.d + +grub_setup-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_parser.d + +grub_setup-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_partition.d + +grub_setup-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_file.d + +grub_setup-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_fs.d + +grub_setup-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-kern_env.d + +grub_setup-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_fshelp.d + +grub_setup-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_affs.d + +grub_setup-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_cpio.d + +grub_setup-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_ext2.d + +grub_setup-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_fat.d + +grub_setup-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_hfs.d + +grub_setup-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_hfsplus.d + +grub_setup-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_iso9660.d + +grub_setup-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_udf.d + +grub_setup-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_jfs.d + +grub_setup-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_minix.d + +grub_setup-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_ntfs.d + +grub_setup-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_ntfscomp.d + +grub_setup-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_reiserfs.d + +grub_setup-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_sfs.d + +grub_setup-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_ufs.d + +grub_setup-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_xfs.d + +grub_setup-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_afs.d + +grub_setup-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-fs_tar.d + +grub_setup-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-partmap_pc.d + +grub_setup-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-partmap_gpt.d + +grub_setup-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-disk_raid.d + +grub_setup-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-disk_mdraid_linux.d + +grub_setup-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-disk_lvm.d + +grub_setup-util_raid.o: util/raid.c $(util/raid.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_raid.d + +grub_setup-util_lvm.o: util/lvm.c $(util/lvm.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-util_lvm.d + +grub_setup-grub_setup_init.o: grub_setup_init.c $(grub_setup_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -MD -c -o $@ $< +-include grub_setup-grub_setup_init.d + + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c +CLEANFILES += grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o +MOSTLYCLEANFILES += grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_misc.d + +grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o + $(CC) -o $@ grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS) + +grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_grub_mkdevicemap.d + +grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_misc.d + + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/host.c disk/loopback.c disk/scsi.c \ + fs/fshelp.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/color.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c +CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_menu_text.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o +MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_echo.d grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_test.d grub_emu-commands_search.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_i386_pc_halt.d grub_emu-commands_reboot.d grub_emu-commands_i386_cpuid.d grub_emu-disk_host.d grub_emu-disk_loopback.d grub_emu-disk_scsi.d grub_emu-fs_fshelp.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-normal_execute.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-normal_lexer.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-grub_script_tab.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_function.d grub_emu-normal_completion.d grub_emu-normal_main.d grub_emu-normal_color.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_menu_text.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-partmap_gpt.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_i386_pc_misc.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_emu_init.d + +grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_menu_text.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o + $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_echo.o grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_test.o grub_emu-commands_search.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_i386_pc_halt.o grub_emu-commands_reboot.o grub_emu-commands_i386_cpuid.o grub_emu-disk_host.o grub_emu-disk_loopback.o grub_emu-disk_scsi.o grub_emu-fs_fshelp.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-normal_execute.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-normal_lexer.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-grub_script_tab.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_function.o grub_emu-normal_completion.o grub_emu-normal_main.o grub_emu-normal_color.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_menu_text.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-partmap_gpt.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_i386_pc_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS) + +grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_boot.d + +grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cat.d + +grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cmp.d + +grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_configfile.d + +grub_emu-commands_echo.o: commands/echo.c $(commands/echo.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_echo.d + +grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_help.d + +grub_emu-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_terminal.d + +grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_ls.d + +grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_test.d + +grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_search.d + +grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_blocklist.d + +grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_hexdump.d + +grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-lib_hexdump.d + +grub_emu-commands_i386_pc_halt.o: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) + $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_i386_pc_halt.d + +grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_reboot.d + +grub_emu-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) + $(CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_i386_cpuid.d + +grub_emu-disk_host.o: disk/host.c $(disk/host.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_host.d + +grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_loopback.d + +grub_emu-disk_scsi.o: disk/scsi.c $(disk/scsi.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_scsi.d + +grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fshelp.d + +grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-io_gzio.d + +grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_device.d + +grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_disk.d + +grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_dl.d + +grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_elf.d + +grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_env.d + +grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_err.d + +grub_emu-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_execute.d + +grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_file.d + +grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_fs.d + +grub_emu-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_lexer.d + +grub_emu-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_loader.d + +grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_main.d + +grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_misc.d + +grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_parser.d + +grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_script_tab.d + +grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_partition.d + +grub_emu-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_rescue.d + +grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_term.d + +grub_emu-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_arg.d + +grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_cmdline.d + +grub_emu-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_command.d + +grub_emu-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_function.d + +grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_completion.d + +grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_main.d + +grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_color.d + +grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu.d + +grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_entry.d + +grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_viewer.d + +grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_text.d + +grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_misc.d + +grub_emu-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_script.d + +grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_amiga.d + +grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_apple.d + +grub_emu-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_pc.d + +grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_sun.d + +grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_acorn.d + +grub_emu-partmap_gpt.o: partmap/gpt.c $(partmap/gpt.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_gpt.d + +grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_affs.d + +grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_cpio.d + +grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fat.d + +grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ext2.d + +grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfs.d + +grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfsplus.d + +grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_iso9660.d + +grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_udf.d + +grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_jfs.d + +grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_minix.d + +grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfs.d + +grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfscomp.d + +grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_reiserfs.d + +grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_sfs.d + +grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ufs.d + +grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_xfs.d + +grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_afs.d + +grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_tar.d + +grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_console.d + +grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostfs.d + +grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_grub_emu.d + +grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_misc.d + +grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostdisk.d + +grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_getroot.d + +grub_emu-util_i386_pc_misc.o: util/i386/pc/misc.c $(util/i386/pc/misc.c_DEPENDENCIES) + $(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_i386_pc_misc.d + +grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid.d + +grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid5_recover.d + +grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid6_recover.d + +grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_mdraid_linux.d + +grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_dmraid_nvidia.d + +grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_lvm.d + +grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_emu_init.d + + +grub_emu_LDFLAGS = $(LIBCURSES) + +ifeq ($(enable_grub_emu_usb), yes) +grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \ + commands/usbtest.c +CLEANFILES += grub-emu$(EXEEXT) grub_emu-disk_usbms.o grub_emu-util_usb.o grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o +MOSTLYCLEANFILES += grub_emu-disk_usbms.d grub_emu-util_usb.d grub_emu-bus_usb_usb.d grub_emu-commands_usbtest.d + +grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-disk_usbms.o grub_emu-util_usb.o grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o + $(CC) -o $@ grub_emu-disk_usbms.o grub_emu-util_usb.o grub_emu-bus_usb_usb.o grub_emu-commands_usbtest.o $(LDFLAGS) $(grub_emu_LDFLAGS) + +grub_emu-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_usbms.d + +grub_emu-util_usb.o: util/usb.c $(util/usb.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_usb.d + +grub_emu-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) + $(CC) -Ibus/usb -I$(srcdir)/bus/usb $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-bus_usb_usb.d + +grub_emu-commands_usbtest.o: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_usbtest.d + +grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB) +endif + +# Scripts. +sbin_SCRIPTS = grub-install +bin_SCRIPTS = grub-mkrescue + +# For grub-install. +grub_install_SOURCES = util/i386/pc/grub-install.in +CLEANFILES += grub-install + +grub-install: util/i386/pc/grub-install.in $(util/i386/pc/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/i386/pc/grub-install.in + chmod +x $@ + + +# For grub-mkrescue. +grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in +CLEANFILES += grub-mkrescue + +grub-mkrescue: util/i386/pc/grub-mkrescue.in $(util/i386/pc/grub-mkrescue.in_DEPENDENCIES) config.status + ./config.status --file=grub-mkrescue:util/i386/pc/grub-mkrescue.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ + _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \ + vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ + ata.mod vga.mod memdisk.mod pci.mod lspci.mod \ + aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ + datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \ + usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod + +# For biosdisk.mod. +biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c +CLEANFILES += biosdisk.mod mod-biosdisk.o mod-biosdisk.c pre-biosdisk.o biosdisk_mod-disk_i386_pc_biosdisk.o und-biosdisk.lst +ifneq ($(biosdisk_mod_EXPORTS),no) +CLEANFILES += def-biosdisk.lst +DEFSYMFILES += def-biosdisk.lst +endif +MOSTLYCLEANFILES += biosdisk_mod-disk_i386_pc_biosdisk.d +UNDSYMFILES += und-biosdisk.lst + +biosdisk.mod: pre-biosdisk.o mod-biosdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(biosdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-biosdisk.o mod-biosdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-biosdisk.o: $(biosdisk_mod_DEPENDENCIES) biosdisk_mod-disk_i386_pc_biosdisk.o + -rm -f $@ + $(TARGET_CC) $(biosdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ biosdisk_mod-disk_i386_pc_biosdisk.o + +mod-biosdisk.o: mod-biosdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -c -o $@ $< + +mod-biosdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'biosdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(biosdisk_mod_EXPORTS),no) +def-biosdisk.lst: pre-biosdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 biosdisk/' > $@ +endif + +und-biosdisk.lst: pre-biosdisk.o + echo 'biosdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +biosdisk_mod-disk_i386_pc_biosdisk.o: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -MD -c -o $@ $< +-include biosdisk_mod-disk_i386_pc_biosdisk.d + +CLEANFILES += cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst fs-biosdisk_mod-disk_i386_pc_biosdisk.lst partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst +COMMANDFILES += cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst +FSFILES += fs-biosdisk_mod-disk_i386_pc_biosdisk.lst +PARTMAPFILES += partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst + +cmd-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh biosdisk > $@ || (rm -f $@; exit 1) + +fs-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh biosdisk > $@ || (rm -f $@; exit 1) + +partmap-biosdisk_mod-disk_i386_pc_biosdisk.lst: disk/i386/pc/biosdisk.c $(disk/i386/pc/biosdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk/i386/pc -I$(srcdir)/disk/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(biosdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh biosdisk > $@ || (rm -f $@; exit 1) + + +biosdisk_mod_CFLAGS = $(COMMON_CFLAGS) +biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/i386/pc/chainloader.c +CLEANFILES += _chain.mod mod-_chain.o mod-_chain.c pre-_chain.o _chain_mod-loader_i386_pc_chainloader.o und-_chain.lst +ifneq ($(_chain_mod_EXPORTS),no) +CLEANFILES += def-_chain.lst +DEFSYMFILES += def-_chain.lst +endif +MOSTLYCLEANFILES += _chain_mod-loader_i386_pc_chainloader.d +UNDSYMFILES += und-_chain.lst + +_chain.mod: pre-_chain.o mod-_chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_chain.o mod-_chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_chain.o: $(_chain_mod_DEPENDENCIES) _chain_mod-loader_i386_pc_chainloader.o + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _chain_mod-loader_i386_pc_chainloader.o + +mod-_chain.o: mod-_chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -c -o $@ $< + +mod-_chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_chain_mod_EXPORTS),no) +def-_chain.lst: pre-_chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _chain/' > $@ +endif + +und-_chain.lst: pre-_chain.o + echo '_chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_chain_mod-loader_i386_pc_chainloader.o: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -MD -c -o $@ $< +-include _chain_mod-loader_i386_pc_chainloader.d + +CLEANFILES += cmd-_chain_mod-loader_i386_pc_chainloader.lst fs-_chain_mod-loader_i386_pc_chainloader.lst partmap-_chain_mod-loader_i386_pc_chainloader.lst +COMMANDFILES += cmd-_chain_mod-loader_i386_pc_chainloader.lst +FSFILES += fs-_chain_mod-loader_i386_pc_chainloader.lst +PARTMAPFILES += partmap-_chain_mod-loader_i386_pc_chainloader.lst + +cmd-_chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _chain > $@ || (rm -f $@; exit 1) + +fs-_chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _chain > $@ || (rm -f $@; exit 1) + +partmap-_chain_mod-loader_i386_pc_chainloader.lst: loader/i386/pc/chainloader.c $(loader/i386/pc/chainloader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _chain > $@ || (rm -f $@; exit 1) + + +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/i386/pc/chainloader_normal.c +CLEANFILES += chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_i386_pc_chainloader_normal.o und-chain.lst +ifneq ($(chain_mod_EXPORTS),no) +CLEANFILES += def-chain.lst +DEFSYMFILES += def-chain.lst +endif +MOSTLYCLEANFILES += chain_mod-loader_i386_pc_chainloader_normal.d +UNDSYMFILES += und-chain.lst + +chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_i386_pc_chainloader_normal.o + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_i386_pc_chainloader_normal.o + +mod-chain.o: mod-chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $< + +mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(chain_mod_EXPORTS),no) +def-chain.lst: pre-chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@ +endif + +und-chain.lst: pre-chain.o + echo 'chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +chain_mod-loader_i386_pc_chainloader_normal.o: loader/i386/pc/chainloader_normal.c $(loader/i386/pc/chainloader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $< +-include chain_mod-loader_i386_pc_chainloader_normal.d + +CLEANFILES += cmd-chain_mod-loader_i386_pc_chainloader_normal.lst fs-chain_mod-loader_i386_pc_chainloader_normal.lst partmap-chain_mod-loader_i386_pc_chainloader_normal.lst +COMMANDFILES += cmd-chain_mod-loader_i386_pc_chainloader_normal.lst +FSFILES += fs-chain_mod-loader_i386_pc_chainloader_normal.lst +PARTMAPFILES += partmap-chain_mod-loader_i386_pc_chainloader_normal.lst + +cmd-chain_mod-loader_i386_pc_chainloader_normal.lst: loader/i386/pc/chainloader_normal.c $(loader/i386/pc/chainloader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1) + +fs-chain_mod-loader_i386_pc_chainloader_normal.lst: loader/i386/pc/chainloader_normal.c $(loader/i386/pc/chainloader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1) + +partmap-chain_mod-loader_i386_pc_chainloader_normal.lst: loader/i386/pc/chainloader_normal.c $(loader/i386/pc/chainloader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1) + + +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/pc/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_i386_pc_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_i386_pc_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_i386_pc_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_i386_pc_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_i386_pc_linux.o: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_i386_pc_linux.d + +CLEANFILES += cmd-_linux_mod-loader_i386_pc_linux.lst fs-_linux_mod-loader_i386_pc_linux.lst partmap-_linux_mod-loader_i386_pc_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_i386_pc_linux.lst +FSFILES += fs-_linux_mod-loader_i386_pc_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_i386_pc_linux.lst + +cmd-_linux_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_i386_pc_linux.lst: loader/i386/pc/linux.c $(loader/i386/pc/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_linux_normal.o: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_linux_normal.lst fs-linux_mod-loader_linux_normal.lst partmap-linux_mod-loader_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_linux_normal.lst +FSFILES += fs-linux_mod-loader_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_linux_normal.lst + +cmd-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_i386_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_i386_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_i386_setjmp.o: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_i386_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_i386_setjmp.lst fs-normal_mod-normal_i386_setjmp.lst partmap-normal_mod-normal_i386_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_i386_setjmp.lst +FSFILES += fs-normal_mod-normal_i386_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_i386_setjmp.lst + +cmd-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_i386_setjmp.lst: normal/i386/setjmp.S $(normal/i386/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/i386 -I$(srcdir)/normal/i386 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/i386/pc/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_i386_pc_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_i386_pc_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_i386_pc_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_i386_pc_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_i386_pc_halt.o: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_i386_pc_halt.d + +CLEANFILES += cmd-halt_mod-commands_i386_pc_halt.lst fs-halt_mod-commands_i386_pc_halt.lst partmap-halt_mod-commands_i386_pc_halt.lst +COMMANDFILES += cmd-halt_mod-commands_i386_pc_halt.lst +FSFILES += fs-halt_mod-commands_i386_pc_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_i386_pc_halt.lst + +cmd-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_i386_pc_halt.lst: commands/i386/pc/halt.c $(commands/i386/pc/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +CLEANFILES += serial.mod mod-serial.o mod-serial.c pre-serial.o serial_mod-term_i386_pc_serial.o und-serial.lst +ifneq ($(serial_mod_EXPORTS),no) +CLEANFILES += def-serial.lst +DEFSYMFILES += def-serial.lst +endif +MOSTLYCLEANFILES += serial_mod-term_i386_pc_serial.d +UNDSYMFILES += und-serial.lst + +serial.mod: pre-serial.o mod-serial.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-serial.o mod-serial.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-serial.o: $(serial_mod_DEPENDENCIES) serial_mod-term_i386_pc_serial.o + -rm -f $@ + $(TARGET_CC) $(serial_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ serial_mod-term_i386_pc_serial.o + +mod-serial.o: mod-serial.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -c -o $@ $< + +mod-serial.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'serial' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(serial_mod_EXPORTS),no) +def-serial.lst: pre-serial.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 serial/' > $@ +endif + +und-serial.lst: pre-serial.o + echo 'serial' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +serial_mod-term_i386_pc_serial.o: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -MD -c -o $@ $< +-include serial_mod-term_i386_pc_serial.d + +CLEANFILES += cmd-serial_mod-term_i386_pc_serial.lst fs-serial_mod-term_i386_pc_serial.lst partmap-serial_mod-term_i386_pc_serial.lst +COMMANDFILES += cmd-serial_mod-term_i386_pc_serial.lst +FSFILES += fs-serial_mod-term_i386_pc_serial.lst +PARTMAPFILES += partmap-serial_mod-term_i386_pc_serial.lst + +cmd-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh serial > $@ || (rm -f $@; exit 1) + +fs-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh serial > $@ || (rm -f $@; exit 1) + +partmap-serial_mod-term_i386_pc_serial.lst: term/i386/pc/serial.c $(term/i386/pc/serial.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(serial_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh serial > $@ || (rm -f $@; exit 1) + + +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \ + loader/i386/pc/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst +ifneq ($(_multiboot_mod_EXPORTS),no) +CLEANFILES += def-_multiboot.lst +DEFSYMFILES += def-_multiboot.lst +endif +MOSTLYCLEANFILES += _multiboot_mod-loader_i386_pc_multiboot.d _multiboot_mod-loader_i386_pc_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d +UNDSYMFILES += und-_multiboot.lst + +_multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_multiboot.o mod-_multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_i386_pc_multiboot.o _multiboot_mod-loader_i386_pc_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + +mod-_multiboot.o: mod-_multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $< + +mod-_multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_multiboot_mod_EXPORTS),no) +def-_multiboot.lst: pre-_multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _multiboot/' > $@ +endif + +und-_multiboot.lst: pre-_multiboot.o + echo '_multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_multiboot_mod-loader_i386_pc_multiboot.o: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_i386_pc_multiboot.d + +CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst fs-_multiboot_mod-loader_i386_pc_multiboot.lst partmap-_multiboot_mod-loader_i386_pc_multiboot.lst +COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot.lst +FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot.lst + +cmd-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_i386_pc_multiboot.lst: loader/i386/pc/multiboot.c $(loader/i386/pc/multiboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_i386_pc_multiboot2.o: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_i386_pc_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst fs-_multiboot_mod-loader_i386_pc_multiboot2.lst partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_i386_pc_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst + +cmd-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_i386_pc_multiboot2.lst: loader/i386/pc/multiboot2.c $(loader/i386/pc/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/pc -I$(srcdir)/loader/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot2.lst fs-_multiboot_mod-loader_multiboot2.lst partmap-_multiboot_mod-loader_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot2.lst + +cmd-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot_loader.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst fs-_multiboot_mod-loader_multiboot_loader.lst partmap-_multiboot_mod-loader_multiboot_loader.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst +FSFILES += fs-_multiboot_mod-loader_multiboot_loader.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot_loader.lst + +cmd-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +CLEANFILES += multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_multiboot_loader_normal.o und-multiboot.lst +ifneq ($(multiboot_mod_EXPORTS),no) +CLEANFILES += def-multiboot.lst +DEFSYMFILES += def-multiboot.lst +endif +MOSTLYCLEANFILES += multiboot_mod-loader_multiboot_loader_normal.d +UNDSYMFILES += und-multiboot.lst + +multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_multiboot_loader_normal.o + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_multiboot_loader_normal.o + +mod-multiboot.o: mod-multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(multiboot_mod_EXPORTS),no) +def-multiboot.lst: pre-multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@ +endif + +und-multiboot.lst: pre-multiboot.o + echo 'multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +multiboot_mod-loader_multiboot_loader_normal.o: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include multiboot_mod-loader_multiboot_loader_normal.d + +CLEANFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst fs-multiboot_mod-loader_multiboot_loader_normal.lst partmap-multiboot_mod-loader_multiboot_loader_normal.lst +COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst +FSFILES += fs-multiboot_mod-loader_multiboot_loader_normal.lst +PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader_normal.lst + +cmd-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1) + +fs-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1) + +partmap-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1) + + +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbe.mod. +vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \ + video/i386/pc/vbefill.c video/i386/pc/vbeutil.c +CLEANFILES += vbe.mod mod-vbe.o mod-vbe.c pre-vbe.o vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o vbe_mod-video_i386_pc_vbeutil.o und-vbe.lst +ifneq ($(vbe_mod_EXPORTS),no) +CLEANFILES += def-vbe.lst +DEFSYMFILES += def-vbe.lst +endif +MOSTLYCLEANFILES += vbe_mod-video_i386_pc_vbe.d vbe_mod-video_i386_pc_vbeblit.d vbe_mod-video_i386_pc_vbefill.d vbe_mod-video_i386_pc_vbeutil.d +UNDSYMFILES += und-vbe.lst + +vbe.mod: pre-vbe.o mod-vbe.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-vbe.o mod-vbe.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-vbe.o: $(vbe_mod_DEPENDENCIES) vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o vbe_mod-video_i386_pc_vbeutil.o + -rm -f $@ + $(TARGET_CC) $(vbe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbe_mod-video_i386_pc_vbe.o vbe_mod-video_i386_pc_vbeblit.o vbe_mod-video_i386_pc_vbefill.o vbe_mod-video_i386_pc_vbeutil.o + +mod-vbe.o: mod-vbe.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -c -o $@ $< + +mod-vbe.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'vbe' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(vbe_mod_EXPORTS),no) +def-vbe.lst: pre-vbe.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbe/' > $@ +endif + +und-vbe.lst: pre-vbe.o + echo 'vbe' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +vbe_mod-video_i386_pc_vbe.o: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -MD -c -o $@ $< +-include vbe_mod-video_i386_pc_vbe.d + +CLEANFILES += cmd-vbe_mod-video_i386_pc_vbe.lst fs-vbe_mod-video_i386_pc_vbe.lst partmap-vbe_mod-video_i386_pc_vbe.lst +COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbe.lst +FSFILES += fs-vbe_mod-video_i386_pc_vbe.lst +PARTMAPFILES += partmap-vbe_mod-video_i386_pc_vbe.lst + +cmd-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1) + +fs-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1) + +partmap-vbe_mod-video_i386_pc_vbe.lst: video/i386/pc/vbe.c $(video/i386/pc/vbe.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbe > $@ || (rm -f $@; exit 1) + + +vbe_mod-video_i386_pc_vbeblit.o: video/i386/pc/vbeblit.c $(video/i386/pc/vbeblit.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -MD -c -o $@ $< +-include vbe_mod-video_i386_pc_vbeblit.d + +CLEANFILES += cmd-vbe_mod-video_i386_pc_vbeblit.lst fs-vbe_mod-video_i386_pc_vbeblit.lst partmap-vbe_mod-video_i386_pc_vbeblit.lst +COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbeblit.lst +FSFILES += fs-vbe_mod-video_i386_pc_vbeblit.lst +PARTMAPFILES += partmap-vbe_mod-video_i386_pc_vbeblit.lst + +cmd-vbe_mod-video_i386_pc_vbeblit.lst: video/i386/pc/vbeblit.c $(video/i386/pc/vbeblit.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1) + +fs-vbe_mod-video_i386_pc_vbeblit.lst: video/i386/pc/vbeblit.c $(video/i386/pc/vbeblit.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1) + +partmap-vbe_mod-video_i386_pc_vbeblit.lst: video/i386/pc/vbeblit.c $(video/i386/pc/vbeblit.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbe > $@ || (rm -f $@; exit 1) + + +vbe_mod-video_i386_pc_vbefill.o: video/i386/pc/vbefill.c $(video/i386/pc/vbefill.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -MD -c -o $@ $< +-include vbe_mod-video_i386_pc_vbefill.d + +CLEANFILES += cmd-vbe_mod-video_i386_pc_vbefill.lst fs-vbe_mod-video_i386_pc_vbefill.lst partmap-vbe_mod-video_i386_pc_vbefill.lst +COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbefill.lst +FSFILES += fs-vbe_mod-video_i386_pc_vbefill.lst +PARTMAPFILES += partmap-vbe_mod-video_i386_pc_vbefill.lst + +cmd-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c $(video/i386/pc/vbefill.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1) + +fs-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c $(video/i386/pc/vbefill.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1) + +partmap-vbe_mod-video_i386_pc_vbefill.lst: video/i386/pc/vbefill.c $(video/i386/pc/vbefill.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbe > $@ || (rm -f $@; exit 1) + + +vbe_mod-video_i386_pc_vbeutil.o: video/i386/pc/vbeutil.c $(video/i386/pc/vbeutil.c_DEPENDENCIES) + $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -MD -c -o $@ $< +-include vbe_mod-video_i386_pc_vbeutil.d + +CLEANFILES += cmd-vbe_mod-video_i386_pc_vbeutil.lst fs-vbe_mod-video_i386_pc_vbeutil.lst partmap-vbe_mod-video_i386_pc_vbeutil.lst +COMMANDFILES += cmd-vbe_mod-video_i386_pc_vbeutil.lst +FSFILES += fs-vbe_mod-video_i386_pc_vbeutil.lst +PARTMAPFILES += partmap-vbe_mod-video_i386_pc_vbeutil.lst + +cmd-vbe_mod-video_i386_pc_vbeutil.lst: video/i386/pc/vbeutil.c $(video/i386/pc/vbeutil.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbe > $@ || (rm -f $@; exit 1) + +fs-vbe_mod-video_i386_pc_vbeutil.lst: video/i386/pc/vbeutil.c $(video/i386/pc/vbeutil.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbe > $@ || (rm -f $@; exit 1) + +partmap-vbe_mod-video_i386_pc_vbeutil.lst: video/i386/pc/vbeutil.c $(video/i386/pc/vbeutil.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ivideo/i386/pc -I$(srcdir)/video/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbe_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbe > $@ || (rm -f $@; exit 1) + + +vbe_mod_CFLAGS = $(COMMON_CFLAGS) +vbe_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbeinfo.mod. +vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c +CLEANFILES += vbeinfo.mod mod-vbeinfo.o mod-vbeinfo.c pre-vbeinfo.o vbeinfo_mod-commands_i386_pc_vbeinfo.o und-vbeinfo.lst +ifneq ($(vbeinfo_mod_EXPORTS),no) +CLEANFILES += def-vbeinfo.lst +DEFSYMFILES += def-vbeinfo.lst +endif +MOSTLYCLEANFILES += vbeinfo_mod-commands_i386_pc_vbeinfo.d +UNDSYMFILES += und-vbeinfo.lst + +vbeinfo.mod: pre-vbeinfo.o mod-vbeinfo.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(vbeinfo_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-vbeinfo.o mod-vbeinfo.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-vbeinfo.o: $(vbeinfo_mod_DEPENDENCIES) vbeinfo_mod-commands_i386_pc_vbeinfo.o + -rm -f $@ + $(TARGET_CC) $(vbeinfo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbeinfo_mod-commands_i386_pc_vbeinfo.o + +mod-vbeinfo.o: mod-vbeinfo.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -c -o $@ $< + +mod-vbeinfo.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'vbeinfo' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(vbeinfo_mod_EXPORTS),no) +def-vbeinfo.lst: pre-vbeinfo.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbeinfo/' > $@ +endif + +und-vbeinfo.lst: pre-vbeinfo.o + echo 'vbeinfo' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +vbeinfo_mod-commands_i386_pc_vbeinfo.o: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -MD -c -o $@ $< +-include vbeinfo_mod-commands_i386_pc_vbeinfo.d + +CLEANFILES += cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst +COMMANDFILES += cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst +FSFILES += fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst +PARTMAPFILES += partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst + +cmd-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbeinfo > $@ || (rm -f $@; exit 1) + +fs-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbeinfo > $@ || (rm -f $@; exit 1) + +partmap-vbeinfo_mod-commands_i386_pc_vbeinfo.lst: commands/i386/pc/vbeinfo.c $(commands/i386/pc/vbeinfo.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbeinfo_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbeinfo > $@ || (rm -f $@; exit 1) + + +vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS) +vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbetest.mod. +vbetest_mod_SOURCES = commands/i386/pc/vbetest.c +CLEANFILES += vbetest.mod mod-vbetest.o mod-vbetest.c pre-vbetest.o vbetest_mod-commands_i386_pc_vbetest.o und-vbetest.lst +ifneq ($(vbetest_mod_EXPORTS),no) +CLEANFILES += def-vbetest.lst +DEFSYMFILES += def-vbetest.lst +endif +MOSTLYCLEANFILES += vbetest_mod-commands_i386_pc_vbetest.d +UNDSYMFILES += und-vbetest.lst + +vbetest.mod: pre-vbetest.o mod-vbetest.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(vbetest_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-vbetest.o mod-vbetest.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-vbetest.o: $(vbetest_mod_DEPENDENCIES) vbetest_mod-commands_i386_pc_vbetest.o + -rm -f $@ + $(TARGET_CC) $(vbetest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vbetest_mod-commands_i386_pc_vbetest.o + +mod-vbetest.o: mod-vbetest.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -c -o $@ $< + +mod-vbetest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'vbetest' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(vbetest_mod_EXPORTS),no) +def-vbetest.lst: pre-vbetest.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vbetest/' > $@ +endif + +und-vbetest.lst: pre-vbetest.o + echo 'vbetest' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +vbetest_mod-commands_i386_pc_vbetest.o: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -MD -c -o $@ $< +-include vbetest_mod-commands_i386_pc_vbetest.d + +CLEANFILES += cmd-vbetest_mod-commands_i386_pc_vbetest.lst fs-vbetest_mod-commands_i386_pc_vbetest.lst partmap-vbetest_mod-commands_i386_pc_vbetest.lst +COMMANDFILES += cmd-vbetest_mod-commands_i386_pc_vbetest.lst +FSFILES += fs-vbetest_mod-commands_i386_pc_vbetest.lst +PARTMAPFILES += partmap-vbetest_mod-commands_i386_pc_vbetest.lst + +cmd-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vbetest > $@ || (rm -f $@; exit 1) + +fs-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vbetest > $@ || (rm -f $@; exit 1) + +partmap-vbetest_mod-commands_i386_pc_vbetest.lst: commands/i386/pc/vbetest.c $(commands/i386/pc/vbetest.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vbetest_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vbetest > $@ || (rm -f $@; exit 1) + + +vbetest_mod_CFLAGS = $(COMMON_CFLAGS) +vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +CLEANFILES += play.mod mod-play.o mod-play.c pre-play.o play_mod-commands_i386_pc_play.o und-play.lst +ifneq ($(play_mod_EXPORTS),no) +CLEANFILES += def-play.lst +DEFSYMFILES += def-play.lst +endif +MOSTLYCLEANFILES += play_mod-commands_i386_pc_play.d +UNDSYMFILES += und-play.lst + +play.mod: pre-play.o mod-play.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-play.o mod-play.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-play.o: $(play_mod_DEPENDENCIES) play_mod-commands_i386_pc_play.o + -rm -f $@ + $(TARGET_CC) $(play_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ play_mod-commands_i386_pc_play.o + +mod-play.o: mod-play.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -c -o $@ $< + +mod-play.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'play' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(play_mod_EXPORTS),no) +def-play.lst: pre-play.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 play/' > $@ +endif + +und-play.lst: pre-play.o + echo 'play' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +play_mod-commands_i386_pc_play.o: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -MD -c -o $@ $< +-include play_mod-commands_i386_pc_play.d + +CLEANFILES += cmd-play_mod-commands_i386_pc_play.lst fs-play_mod-commands_i386_pc_play.lst partmap-play_mod-commands_i386_pc_play.lst +COMMANDFILES += cmd-play_mod-commands_i386_pc_play.lst +FSFILES += fs-play_mod-commands_i386_pc_play.lst +PARTMAPFILES += partmap-play_mod-commands_i386_pc_play.lst + +cmd-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh play > $@ || (rm -f $@; exit 1) + +fs-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh play > $@ || (rm -f $@; exit 1) + +partmap-play_mod-commands_i386_pc_play.lst: commands/i386/pc/play.c $(commands/i386/pc/play.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(play_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh play > $@ || (rm -f $@; exit 1) + + +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata.mod. +ata_mod_SOURCES = disk/ata.c +CLEANFILES += ata.mod mod-ata.o mod-ata.c pre-ata.o ata_mod-disk_ata.o und-ata.lst +ifneq ($(ata_mod_EXPORTS),no) +CLEANFILES += def-ata.lst +DEFSYMFILES += def-ata.lst +endif +MOSTLYCLEANFILES += ata_mod-disk_ata.d +UNDSYMFILES += und-ata.lst + +ata.mod: pre-ata.o mod-ata.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ata.o mod-ata.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ata.o: $(ata_mod_DEPENDENCIES) ata_mod-disk_ata.o + -rm -f $@ + $(TARGET_CC) $(ata_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_mod-disk_ata.o + +mod-ata.o: mod-ata.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -c -o $@ $< + +mod-ata.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ata' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ata_mod_EXPORTS),no) +def-ata.lst: pre-ata.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata/' > $@ +endif + +und-ata.lst: pre-ata.o + echo 'ata' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ata_mod-disk_ata.o: disk/ata.c $(disk/ata.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -MD -c -o $@ $< +-include ata_mod-disk_ata.d + +CLEANFILES += cmd-ata_mod-disk_ata.lst fs-ata_mod-disk_ata.lst partmap-ata_mod-disk_ata.lst +COMMANDFILES += cmd-ata_mod-disk_ata.lst +FSFILES += fs-ata_mod-disk_ata.lst +PARTMAPFILES += partmap-ata_mod-disk_ata.lst + +cmd-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ata > $@ || (rm -f $@; exit 1) + +fs-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ata > $@ || (rm -f $@; exit 1) + +partmap-ata_mod-disk_ata.lst: disk/ata.c $(disk/ata.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ata > $@ || (rm -f $@; exit 1) + + +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vga.mod. +vga_mod_SOURCES = term/i386/pc/vga.c +CLEANFILES += vga.mod mod-vga.o mod-vga.c pre-vga.o vga_mod-term_i386_pc_vga.o und-vga.lst +ifneq ($(vga_mod_EXPORTS),no) +CLEANFILES += def-vga.lst +DEFSYMFILES += def-vga.lst +endif +MOSTLYCLEANFILES += vga_mod-term_i386_pc_vga.d +UNDSYMFILES += und-vga.lst + +vga.mod: pre-vga.o mod-vga.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(vga_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-vga.o mod-vga.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-vga.o: $(vga_mod_DEPENDENCIES) vga_mod-term_i386_pc_vga.o + -rm -f $@ + $(TARGET_CC) $(vga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vga_mod-term_i386_pc_vga.o + +mod-vga.o: mod-vga.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -c -o $@ $< + +mod-vga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'vga' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(vga_mod_EXPORTS),no) +def-vga.lst: pre-vga.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vga/' > $@ +endif + +und-vga.lst: pre-vga.o + echo 'vga' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +vga_mod-term_i386_pc_vga.o: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -MD -c -o $@ $< +-include vga_mod-term_i386_pc_vga.d + +CLEANFILES += cmd-vga_mod-term_i386_pc_vga.lst fs-vga_mod-term_i386_pc_vga.lst partmap-vga_mod-term_i386_pc_vga.lst +COMMANDFILES += cmd-vga_mod-term_i386_pc_vga.lst +FSFILES += fs-vga_mod-term_i386_pc_vga.lst +PARTMAPFILES += partmap-vga_mod-term_i386_pc_vga.lst + +cmd-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vga > $@ || (rm -f $@; exit 1) + +fs-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vga > $@ || (rm -f $@; exit 1) + +partmap-vga_mod-term_i386_pc_vga.lst: term/i386/pc/vga.c $(term/i386/pc/vga.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vga > $@ || (rm -f $@; exit 1) + + +vga_mod_CFLAGS = $(COMMON_CFLAGS) +vga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst +PARTMAPFILES += partmap-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + +partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst +PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + +partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod +aout_mod_SOURCES = loader/aout.c +CLEANFILES += aout.mod mod-aout.o mod-aout.c pre-aout.o aout_mod-loader_aout.o und-aout.lst +ifneq ($(aout_mod_EXPORTS),no) +CLEANFILES += def-aout.lst +DEFSYMFILES += def-aout.lst +endif +MOSTLYCLEANFILES += aout_mod-loader_aout.d +UNDSYMFILES += und-aout.lst + +aout.mod: pre-aout.o mod-aout.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-aout.o mod-aout.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-aout.o: $(aout_mod_DEPENDENCIES) aout_mod-loader_aout.o + -rm -f $@ + $(TARGET_CC) $(aout_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ aout_mod-loader_aout.o + +mod-aout.o: mod-aout.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -c -o $@ $< + +mod-aout.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'aout' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(aout_mod_EXPORTS),no) +def-aout.lst: pre-aout.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 aout/' > $@ +endif + +und-aout.lst: pre-aout.o + echo 'aout' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +aout_mod-loader_aout.o: loader/aout.c $(loader/aout.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -MD -c -o $@ $< +-include aout_mod-loader_aout.d + +CLEANFILES += cmd-aout_mod-loader_aout.lst fs-aout_mod-loader_aout.lst partmap-aout_mod-loader_aout.lst +COMMANDFILES += cmd-aout_mod-loader_aout.lst +FSFILES += fs-aout_mod-loader_aout.lst +PARTMAPFILES += partmap-aout_mod-loader_aout.lst + +cmd-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh aout > $@ || (rm -f $@; exit 1) + +fs-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh aout > $@ || (rm -f $@; exit 1) + +partmap-aout_mod-loader_aout.lst: loader/aout.c $(loader/aout.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(aout_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh aout > $@ || (rm -f $@; exit 1) + + +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _bsd.mod +_bsd_mod_SOURCES = loader/i386/bsd.c +CLEANFILES += _bsd.mod mod-_bsd.o mod-_bsd.c pre-_bsd.o _bsd_mod-loader_i386_bsd.o und-_bsd.lst +ifneq ($(_bsd_mod_EXPORTS),no) +CLEANFILES += def-_bsd.lst +DEFSYMFILES += def-_bsd.lst +endif +MOSTLYCLEANFILES += _bsd_mod-loader_i386_bsd.d +UNDSYMFILES += und-_bsd.lst + +_bsd.mod: pre-_bsd.o mod-_bsd.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_bsd.o mod-_bsd.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_bsd.o: $(_bsd_mod_DEPENDENCIES) _bsd_mod-loader_i386_bsd.o + -rm -f $@ + $(TARGET_CC) $(_bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _bsd_mod-loader_i386_bsd.o + +mod-_bsd.o: mod-_bsd.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_bsd_mod_CFLAGS) -c -o $@ $< + +mod-_bsd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_bsd' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_bsd_mod_EXPORTS),no) +def-_bsd.lst: pre-_bsd.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _bsd/' > $@ +endif + +und-_bsd.lst: pre-_bsd.o + echo '_bsd' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_bsd_mod-loader_i386_bsd.o: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_bsd_mod_CFLAGS) -MD -c -o $@ $< +-include _bsd_mod-loader_i386_bsd.d + +CLEANFILES += cmd-_bsd_mod-loader_i386_bsd.lst fs-_bsd_mod-loader_i386_bsd.lst partmap-_bsd_mod-loader_i386_bsd.lst +COMMANDFILES += cmd-_bsd_mod-loader_i386_bsd.lst +FSFILES += fs-_bsd_mod-loader_i386_bsd.lst +PARTMAPFILES += partmap-_bsd_mod-loader_i386_bsd.lst + +cmd-_bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_bsd_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _bsd > $@ || (rm -f $@; exit 1) + +fs-_bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_bsd_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _bsd > $@ || (rm -f $@; exit 1) + +partmap-_bsd_mod-loader_i386_bsd.lst: loader/i386/bsd.c $(loader/i386/bsd.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_bsd_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _bsd > $@ || (rm -f $@; exit 1) + + +_bsd_mod_CFLAGS = $(COMMON_CFLAGS) +_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +bsd_mod_SOURCES = loader/i386/bsd_normal.c +CLEANFILES += bsd.mod mod-bsd.o mod-bsd.c pre-bsd.o bsd_mod-loader_i386_bsd_normal.o und-bsd.lst +ifneq ($(bsd_mod_EXPORTS),no) +CLEANFILES += def-bsd.lst +DEFSYMFILES += def-bsd.lst +endif +MOSTLYCLEANFILES += bsd_mod-loader_i386_bsd_normal.d +UNDSYMFILES += und-bsd.lst + +bsd.mod: pre-bsd.o mod-bsd.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-bsd.o mod-bsd.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-bsd.o: $(bsd_mod_DEPENDENCIES) bsd_mod-loader_i386_bsd_normal.o + -rm -f $@ + $(TARGET_CC) $(bsd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ bsd_mod-loader_i386_bsd_normal.o + +mod-bsd.o: mod-bsd.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -c -o $@ $< + +mod-bsd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'bsd' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(bsd_mod_EXPORTS),no) +def-bsd.lst: pre-bsd.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 bsd/' > $@ +endif + +und-bsd.lst: pre-bsd.o + echo 'bsd' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +bsd_mod-loader_i386_bsd_normal.o: loader/i386/bsd_normal.c $(loader/i386/bsd_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -MD -c -o $@ $< +-include bsd_mod-loader_i386_bsd_normal.d + +CLEANFILES += cmd-bsd_mod-loader_i386_bsd_normal.lst fs-bsd_mod-loader_i386_bsd_normal.lst partmap-bsd_mod-loader_i386_bsd_normal.lst +COMMANDFILES += cmd-bsd_mod-loader_i386_bsd_normal.lst +FSFILES += fs-bsd_mod-loader_i386_bsd_normal.lst +PARTMAPFILES += partmap-bsd_mod-loader_i386_bsd_normal.lst + +cmd-bsd_mod-loader_i386_bsd_normal.lst: loader/i386/bsd_normal.c $(loader/i386/bsd_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh bsd > $@ || (rm -f $@; exit 1) + +fs-bsd_mod-loader_i386_bsd_normal.lst: loader/i386/bsd_normal.c $(loader/i386/bsd_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh bsd > $@ || (rm -f $@; exit 1) + +partmap-bsd_mod-loader_i386_bsd_normal.lst: loader/i386/bsd_normal.c $(loader/i386/bsd_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386 -I$(srcdir)/loader/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(bsd_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh bsd > $@ || (rm -f $@; exit 1) + + +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +CLEANFILES += usb.mod mod-usb.o mod-usb.c pre-usb.o usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o und-usb.lst +ifneq ($(usb_mod_EXPORTS),no) +CLEANFILES += def-usb.lst +DEFSYMFILES += def-usb.lst +endif +MOSTLYCLEANFILES += usb_mod-bus_usb_usb.d usb_mod-bus_usb_usbtrans.d usb_mod-bus_usb_usbhub.d +UNDSYMFILES += und-usb.lst + +usb.mod: pre-usb.o mod-usb.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-usb.o mod-usb.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-usb.o: $(usb_mod_DEPENDENCIES) usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o + -rm -f $@ + $(TARGET_CC) $(usb_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usb_mod-bus_usb_usb.o usb_mod-bus_usb_usbtrans.o usb_mod-bus_usb_usbhub.o + +mod-usb.o: mod-usb.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -c -o $@ $< + +mod-usb.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'usb' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(usb_mod_EXPORTS),no) +def-usb.lst: pre-usb.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usb/' > $@ +endif + +und-usb.lst: pre-usb.o + echo 'usb' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +usb_mod-bus_usb_usb.o: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) + $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $< +-include usb_mod-bus_usb_usb.d + +CLEANFILES += cmd-usb_mod-bus_usb_usb.lst fs-usb_mod-bus_usb_usb.lst partmap-usb_mod-bus_usb_usb.lst +COMMANDFILES += cmd-usb_mod-bus_usb_usb.lst +FSFILES += fs-usb_mod-bus_usb_usb.lst +PARTMAPFILES += partmap-usb_mod-bus_usb_usb.lst + +cmd-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1) + +fs-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1) + +partmap-usb_mod-bus_usb_usb.lst: bus/usb/usb.c $(bus/usb/usb.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1) + + +usb_mod-bus_usb_usbtrans.o: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) + $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $< +-include usb_mod-bus_usb_usbtrans.d + +CLEANFILES += cmd-usb_mod-bus_usb_usbtrans.lst fs-usb_mod-bus_usb_usbtrans.lst partmap-usb_mod-bus_usb_usbtrans.lst +COMMANDFILES += cmd-usb_mod-bus_usb_usbtrans.lst +FSFILES += fs-usb_mod-bus_usb_usbtrans.lst +PARTMAPFILES += partmap-usb_mod-bus_usb_usbtrans.lst + +cmd-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1) + +fs-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1) + +partmap-usb_mod-bus_usb_usbtrans.lst: bus/usb/usbtrans.c $(bus/usb/usbtrans.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1) + + +usb_mod-bus_usb_usbhub.o: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) + $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -MD -c -o $@ $< +-include usb_mod-bus_usb_usbhub.d + +CLEANFILES += cmd-usb_mod-bus_usb_usbhub.lst fs-usb_mod-bus_usb_usbhub.lst partmap-usb_mod-bus_usb_usbhub.lst +COMMANDFILES += cmd-usb_mod-bus_usb_usbhub.lst +FSFILES += fs-usb_mod-bus_usb_usbhub.lst +PARTMAPFILES += partmap-usb_mod-bus_usb_usbhub.lst + +cmd-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usb > $@ || (rm -f $@; exit 1) + +fs-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usb > $@ || (rm -f $@; exit 1) + +partmap-usb_mod-bus_usb_usbhub.lst: bus/usb/usbhub.c $(bus/usb/usbhub.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usb > $@ || (rm -f $@; exit 1) + + +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +CLEANFILES += usbtest.mod mod-usbtest.o mod-usbtest.c pre-usbtest.o usbtest_mod-commands_usbtest.o und-usbtest.lst +ifneq ($(usbtest_mod_EXPORTS),no) +CLEANFILES += def-usbtest.lst +DEFSYMFILES += def-usbtest.lst +endif +MOSTLYCLEANFILES += usbtest_mod-commands_usbtest.d +UNDSYMFILES += und-usbtest.lst + +usbtest.mod: pre-usbtest.o mod-usbtest.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-usbtest.o mod-usbtest.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-usbtest.o: $(usbtest_mod_DEPENDENCIES) usbtest_mod-commands_usbtest.o + -rm -f $@ + $(TARGET_CC) $(usbtest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usbtest_mod-commands_usbtest.o + +mod-usbtest.o: mod-usbtest.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -c -o $@ $< + +mod-usbtest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'usbtest' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(usbtest_mod_EXPORTS),no) +def-usbtest.lst: pre-usbtest.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbtest/' > $@ +endif + +und-usbtest.lst: pre-usbtest.o + echo 'usbtest' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +usbtest_mod-commands_usbtest.o: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -MD -c -o $@ $< +-include usbtest_mod-commands_usbtest.d + +CLEANFILES += cmd-usbtest_mod-commands_usbtest.lst fs-usbtest_mod-commands_usbtest.lst partmap-usbtest_mod-commands_usbtest.lst +COMMANDFILES += cmd-usbtest_mod-commands_usbtest.lst +FSFILES += fs-usbtest_mod-commands_usbtest.lst +PARTMAPFILES += partmap-usbtest_mod-commands_usbtest.lst + +cmd-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usbtest > $@ || (rm -f $@; exit 1) + +fs-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usbtest > $@ || (rm -f $@; exit 1) + +partmap-usbtest_mod-commands_usbtest.lst: commands/usbtest.c $(commands/usbtest.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbtest_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usbtest > $@ || (rm -f $@; exit 1) + + +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For uhci.mod +uhci_mod_SOURCES = bus/usb/uhci.c +CLEANFILES += uhci.mod mod-uhci.o mod-uhci.c pre-uhci.o uhci_mod-bus_usb_uhci.o und-uhci.lst +ifneq ($(uhci_mod_EXPORTS),no) +CLEANFILES += def-uhci.lst +DEFSYMFILES += def-uhci.lst +endif +MOSTLYCLEANFILES += uhci_mod-bus_usb_uhci.d +UNDSYMFILES += und-uhci.lst + +uhci.mod: pre-uhci.o mod-uhci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-uhci.o mod-uhci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-uhci.o: $(uhci_mod_DEPENDENCIES) uhci_mod-bus_usb_uhci.o + -rm -f $@ + $(TARGET_CC) $(uhci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ uhci_mod-bus_usb_uhci.o + +mod-uhci.o: mod-uhci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -c -o $@ $< + +mod-uhci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'uhci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(uhci_mod_EXPORTS),no) +def-uhci.lst: pre-uhci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 uhci/' > $@ +endif + +und-uhci.lst: pre-uhci.o + echo 'uhci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +uhci_mod-bus_usb_uhci.o: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -MD -c -o $@ $< +-include uhci_mod-bus_usb_uhci.d + +CLEANFILES += cmd-uhci_mod-bus_usb_uhci.lst fs-uhci_mod-bus_usb_uhci.lst partmap-uhci_mod-bus_usb_uhci.lst +COMMANDFILES += cmd-uhci_mod-bus_usb_uhci.lst +FSFILES += fs-uhci_mod-bus_usb_uhci.lst +PARTMAPFILES += partmap-uhci_mod-bus_usb_uhci.lst + +cmd-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh uhci > $@ || (rm -f $@; exit 1) + +fs-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh uhci > $@ || (rm -f $@; exit 1) + +partmap-uhci_mod-bus_usb_uhci.lst: bus/usb/uhci.c $(bus/usb/uhci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(uhci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh uhci > $@ || (rm -f $@; exit 1) + + +uhci_mod_CFLAGS = $(COMMON_CFLAGS) +uhci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +CLEANFILES += ohci.mod mod-ohci.o mod-ohci.c pre-ohci.o ohci_mod-bus_usb_ohci.o und-ohci.lst +ifneq ($(ohci_mod_EXPORTS),no) +CLEANFILES += def-ohci.lst +DEFSYMFILES += def-ohci.lst +endif +MOSTLYCLEANFILES += ohci_mod-bus_usb_ohci.d +UNDSYMFILES += und-ohci.lst + +ohci.mod: pre-ohci.o mod-ohci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ohci.o mod-ohci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ohci.o: $(ohci_mod_DEPENDENCIES) ohci_mod-bus_usb_ohci.o + -rm -f $@ + $(TARGET_CC) $(ohci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ohci_mod-bus_usb_ohci.o + +mod-ohci.o: mod-ohci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -c -o $@ $< + +mod-ohci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ohci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ohci_mod_EXPORTS),no) +def-ohci.lst: pre-ohci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ohci/' > $@ +endif + +und-ohci.lst: pre-ohci.o + echo 'ohci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ohci_mod-bus_usb_ohci.o: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -MD -c -o $@ $< +-include ohci_mod-bus_usb_ohci.d + +CLEANFILES += cmd-ohci_mod-bus_usb_ohci.lst fs-ohci_mod-bus_usb_ohci.lst partmap-ohci_mod-bus_usb_ohci.lst +COMMANDFILES += cmd-ohci_mod-bus_usb_ohci.lst +FSFILES += fs-ohci_mod-bus_usb_ohci.lst +PARTMAPFILES += partmap-ohci_mod-bus_usb_ohci.lst + +cmd-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ohci > $@ || (rm -f $@; exit 1) + +fs-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ohci > $@ || (rm -f $@; exit 1) + +partmap-ohci_mod-bus_usb_ohci.lst: bus/usb/ohci.c $(bus/usb/ohci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus/usb -I$(srcdir)/bus/usb $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ohci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ohci > $@ || (rm -f $@; exit 1) + + +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +usbms_mod_SOURCES = disk/usbms.c +CLEANFILES += usbms.mod mod-usbms.o mod-usbms.c pre-usbms.o usbms_mod-disk_usbms.o und-usbms.lst +ifneq ($(usbms_mod_EXPORTS),no) +CLEANFILES += def-usbms.lst +DEFSYMFILES += def-usbms.lst +endif +MOSTLYCLEANFILES += usbms_mod-disk_usbms.d +UNDSYMFILES += und-usbms.lst + +usbms.mod: pre-usbms.o mod-usbms.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-usbms.o mod-usbms.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-usbms.o: $(usbms_mod_DEPENDENCIES) usbms_mod-disk_usbms.o + -rm -f $@ + $(TARGET_CC) $(usbms_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usbms_mod-disk_usbms.o + +mod-usbms.o: mod-usbms.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -c -o $@ $< + +mod-usbms.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'usbms' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(usbms_mod_EXPORTS),no) +def-usbms.lst: pre-usbms.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usbms/' > $@ +endif + +und-usbms.lst: pre-usbms.o + echo 'usbms' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +usbms_mod-disk_usbms.o: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -MD -c -o $@ $< +-include usbms_mod-disk_usbms.d + +CLEANFILES += cmd-usbms_mod-disk_usbms.lst fs-usbms_mod-disk_usbms.lst partmap-usbms_mod-disk_usbms.lst +COMMANDFILES += cmd-usbms_mod-disk_usbms.lst +FSFILES += fs-usbms_mod-disk_usbms.lst +PARTMAPFILES += partmap-usbms_mod-disk_usbms.lst + +cmd-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usbms > $@ || (rm -f $@; exit 1) + +fs-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usbms > $@ || (rm -f $@; exit 1) + +partmap-usbms_mod-disk_usbms.lst: disk/usbms.c $(disk/usbms.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usbms_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usbms > $@ || (rm -f $@; exit 1) + + +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +CLEANFILES += usb_keyboard.mod mod-usb_keyboard.o mod-usb_keyboard.c pre-usb_keyboard.o usb_keyboard_mod-term_usb_keyboard.o und-usb_keyboard.lst +ifneq ($(usb_keyboard_mod_EXPORTS),no) +CLEANFILES += def-usb_keyboard.lst +DEFSYMFILES += def-usb_keyboard.lst +endif +MOSTLYCLEANFILES += usb_keyboard_mod-term_usb_keyboard.d +UNDSYMFILES += und-usb_keyboard.lst + +usb_keyboard.mod: pre-usb_keyboard.o mod-usb_keyboard.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-usb_keyboard.o mod-usb_keyboard.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-usb_keyboard.o: $(usb_keyboard_mod_DEPENDENCIES) usb_keyboard_mod-term_usb_keyboard.o + -rm -f $@ + $(TARGET_CC) $(usb_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ usb_keyboard_mod-term_usb_keyboard.o + +mod-usb_keyboard.o: mod-usb_keyboard.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -c -o $@ $< + +mod-usb_keyboard.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'usb_keyboard' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(usb_keyboard_mod_EXPORTS),no) +def-usb_keyboard.lst: pre-usb_keyboard.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 usb_keyboard/' > $@ +endif + +und-usb_keyboard.lst: pre-usb_keyboard.o + echo 'usb_keyboard' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +usb_keyboard_mod-term_usb_keyboard.o: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) + $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -MD -c -o $@ $< +-include usb_keyboard_mod-term_usb_keyboard.d + +CLEANFILES += cmd-usb_keyboard_mod-term_usb_keyboard.lst fs-usb_keyboard_mod-term_usb_keyboard.lst partmap-usb_keyboard_mod-term_usb_keyboard.lst +COMMANDFILES += cmd-usb_keyboard_mod-term_usb_keyboard.lst +FSFILES += fs-usb_keyboard_mod-term_usb_keyboard.lst +PARTMAPFILES += partmap-usb_keyboard_mod-term_usb_keyboard.lst + +cmd-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh usb_keyboard > $@ || (rm -f $@; exit 1) + +fs-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh usb_keyboard > $@ || (rm -f $@; exit 1) + +partmap-usb_keyboard_mod-term_usb_keyboard.lst: term/usb_keyboard.c $(term/usb_keyboard.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm -I$(srcdir)/term $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(usb_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh usb_keyboard > $@ || (rm -f $@; exit 1) + + +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pxe.mod +pxe_mod_SOURCES = fs/i386/pc/pxe.c +CLEANFILES += pxe.mod mod-pxe.o mod-pxe.c pre-pxe.o pxe_mod-fs_i386_pc_pxe.o und-pxe.lst +ifneq ($(pxe_mod_EXPORTS),no) +CLEANFILES += def-pxe.lst +DEFSYMFILES += def-pxe.lst +endif +MOSTLYCLEANFILES += pxe_mod-fs_i386_pc_pxe.d +UNDSYMFILES += und-pxe.lst + +pxe.mod: pre-pxe.o mod-pxe.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pxe_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pxe.o mod-pxe.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pxe.o: $(pxe_mod_DEPENDENCIES) pxe_mod-fs_i386_pc_pxe.o + -rm -f $@ + $(TARGET_CC) $(pxe_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pxe_mod-fs_i386_pc_pxe.o + +mod-pxe.o: mod-pxe.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -c -o $@ $< + +mod-pxe.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pxe' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pxe_mod_EXPORTS),no) +def-pxe.lst: pre-pxe.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pxe/' > $@ +endif + +und-pxe.lst: pre-pxe.o + echo 'pxe' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pxe_mod-fs_i386_pc_pxe.o: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) + $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -MD -c -o $@ $< +-include pxe_mod-fs_i386_pc_pxe.d + +CLEANFILES += cmd-pxe_mod-fs_i386_pc_pxe.lst fs-pxe_mod-fs_i386_pc_pxe.lst partmap-pxe_mod-fs_i386_pc_pxe.lst +COMMANDFILES += cmd-pxe_mod-fs_i386_pc_pxe.lst +FSFILES += fs-pxe_mod-fs_i386_pc_pxe.lst +PARTMAPFILES += partmap-pxe_mod-fs_i386_pc_pxe.lst + +cmd-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pxe > $@ || (rm -f $@; exit 1) + +fs-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pxe > $@ || (rm -f $@; exit 1) + +partmap-pxe_mod-fs_i386_pc_pxe.lst: fs/i386/pc/pxe.c $(fs/i386/pc/pxe.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs/i386/pc -I$(srcdir)/fs/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxe_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pxe > $@ || (rm -f $@; exit 1) + + +pxe_mod_CFLAGS = $(COMMON_CFLAGS) +pxe_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pxecmd.mod +pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c +CLEANFILES += pxecmd.mod mod-pxecmd.o mod-pxecmd.c pre-pxecmd.o pxecmd_mod-commands_i386_pc_pxecmd.o und-pxecmd.lst +ifneq ($(pxecmd_mod_EXPORTS),no) +CLEANFILES += def-pxecmd.lst +DEFSYMFILES += def-pxecmd.lst +endif +MOSTLYCLEANFILES += pxecmd_mod-commands_i386_pc_pxecmd.d +UNDSYMFILES += und-pxecmd.lst + +pxecmd.mod: pre-pxecmd.o mod-pxecmd.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pxecmd_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pxecmd.o mod-pxecmd.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pxecmd.o: $(pxecmd_mod_DEPENDENCIES) pxecmd_mod-commands_i386_pc_pxecmd.o + -rm -f $@ + $(TARGET_CC) $(pxecmd_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pxecmd_mod-commands_i386_pc_pxecmd.o + +mod-pxecmd.o: mod-pxecmd.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -c -o $@ $< + +mod-pxecmd.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pxecmd' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pxecmd_mod_EXPORTS),no) +def-pxecmd.lst: pre-pxecmd.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pxecmd/' > $@ +endif + +und-pxecmd.lst: pre-pxecmd.o + echo 'pxecmd' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pxecmd_mod-commands_i386_pc_pxecmd.o: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -MD -c -o $@ $< +-include pxecmd_mod-commands_i386_pc_pxecmd.d + +CLEANFILES += cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst fs-pxecmd_mod-commands_i386_pc_pxecmd.lst partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst +COMMANDFILES += cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst +FSFILES += fs-pxecmd_mod-commands_i386_pc_pxecmd.lst +PARTMAPFILES += partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst + +cmd-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pxecmd > $@ || (rm -f $@; exit 1) + +fs-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pxecmd > $@ || (rm -f $@; exit 1) + +partmap-pxecmd_mod-commands_i386_pc_pxecmd.lst: commands/i386/pc/pxecmd.c $(commands/i386/pc/pxecmd.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pxecmd_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pxecmd > $@ || (rm -f $@; exit 1) + + +pxecmd_mod_CFLAGS = $(COMMON_CFLAGS) +pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +CLEANFILES += datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o und-datetime.lst +ifneq ($(datetime_mod_EXPORTS),no) +CLEANFILES += def-datetime.lst +DEFSYMFILES += def-datetime.lst +endif +MOSTLYCLEANFILES += datetime_mod-lib_datetime.d datetime_mod-lib_i386_datetime.d +UNDSYMFILES += und-datetime.lst + +datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_datetime.o datetime_mod-lib_i386_datetime.o + +mod-datetime.o: mod-datetime.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $< + +mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datetime_mod_EXPORTS),no) +def-datetime.lst: pre-datetime.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@ +endif + +und-datetime.lst: pre-datetime.o + echo 'datetime' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datetime_mod-lib_datetime.o: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_datetime.lst fs-datetime_mod-lib_datetime.lst partmap-datetime_mod-lib_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_datetime.lst +FSFILES += fs-datetime_mod-lib_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_datetime.lst + +cmd-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod-lib_i386_datetime.o: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_i386_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_i386_datetime.lst fs-datetime_mod-lib_i386_datetime.lst partmap-datetime_mod-lib_i386_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_i386_datetime.lst +FSFILES += fs-datetime_mod-lib_i386_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_i386_datetime.lst + +cmd-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_i386_datetime.lst: lib/i386/datetime.c $(lib/i386/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib/i386 -I$(srcdir)/lib/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +CLEANFILES += date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst +ifneq ($(date_mod_EXPORTS),no) +CLEANFILES += def-date.lst +DEFSYMFILES += def-date.lst +endif +MOSTLYCLEANFILES += date_mod-commands_date.d +UNDSYMFILES += und-date.lst + +date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o + +mod-date.o: mod-date.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $< + +mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(date_mod_EXPORTS),no) +def-date.lst: pre-date.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@ +endif + +und-date.lst: pre-date.o + echo 'date' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $< +-include date_mod-commands_date.d + +CLEANFILES += cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst +COMMANDFILES += cmd-date_mod-commands_date.lst +FSFILES += fs-date_mod-commands_date.lst +PARTMAPFILES += partmap-date_mod-commands_date.lst + +cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1) + +fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1) + +partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1) + + +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +CLEANFILES += datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst +ifneq ($(datehook_mod_EXPORTS),no) +CLEANFILES += def-datehook.lst +DEFSYMFILES += def-datehook.lst +endif +MOSTLYCLEANFILES += datehook_mod-hook_datehook.d +UNDSYMFILES += und-datehook.lst + +datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o + +mod-datehook.o: mod-datehook.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $< + +mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datehook_mod_EXPORTS),no) +def-datehook.lst: pre-datehook.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@ +endif + +und-datehook.lst: pre-datehook.o + echo 'datehook' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) + $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $< +-include datehook_mod-hook_datehook.d + +CLEANFILES += cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst +COMMANDFILES += cmd-datehook_mod-hook_datehook.lst +FSFILES += fs-datehook_mod-hook_datehook.lst +PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst + +cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1) + +fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1) + +partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1) + + +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +CLEANFILES += lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst +ifneq ($(lsmmap_mod_EXPORTS),no) +CLEANFILES += def-lsmmap.lst +DEFSYMFILES += def-lsmmap.lst +endif +MOSTLYCLEANFILES += lsmmap_mod-commands_lsmmap.d +UNDSYMFILES += und-lsmmap.lst + +lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o + +mod-lsmmap.o: mod-lsmmap.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $< + +mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lsmmap_mod_EXPORTS),no) +def-lsmmap.lst: pre-lsmmap.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@ +endif + +und-lsmmap.lst: pre-lsmmap.o + echo 'lsmmap' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $< +-include lsmmap_mod-commands_lsmmap.d + +CLEANFILES += cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst +COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst +FSFILES += fs-lsmmap_mod-commands_lsmmap.lst +PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst + +cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1) + +fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1) + +partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1) + + +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata_pthru.mod. +ata_pthru_mod_SOURCES = disk/ata_pthru.c +CLEANFILES += ata_pthru.mod mod-ata_pthru.o mod-ata_pthru.c pre-ata_pthru.o ata_pthru_mod-disk_ata_pthru.o und-ata_pthru.lst +ifneq ($(ata_pthru_mod_EXPORTS),no) +CLEANFILES += def-ata_pthru.lst +DEFSYMFILES += def-ata_pthru.lst +endif +MOSTLYCLEANFILES += ata_pthru_mod-disk_ata_pthru.d +UNDSYMFILES += und-ata_pthru.lst + +ata_pthru.mod: pre-ata_pthru.o mod-ata_pthru.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ata_pthru_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ata_pthru.o mod-ata_pthru.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ata_pthru.o: $(ata_pthru_mod_DEPENDENCIES) ata_pthru_mod-disk_ata_pthru.o + -rm -f $@ + $(TARGET_CC) $(ata_pthru_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ata_pthru_mod-disk_ata_pthru.o + +mod-ata_pthru.o: mod-ata_pthru.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -c -o $@ $< + +mod-ata_pthru.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ata_pthru' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ata_pthru_mod_EXPORTS),no) +def-ata_pthru.lst: pre-ata_pthru.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ata_pthru/' > $@ +endif + +und-ata_pthru.lst: pre-ata_pthru.o + echo 'ata_pthru' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ata_pthru_mod-disk_ata_pthru.o: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -MD -c -o $@ $< +-include ata_pthru_mod-disk_ata_pthru.d + +CLEANFILES += cmd-ata_pthru_mod-disk_ata_pthru.lst fs-ata_pthru_mod-disk_ata_pthru.lst partmap-ata_pthru_mod-disk_ata_pthru.lst +COMMANDFILES += cmd-ata_pthru_mod-disk_ata_pthru.lst +FSFILES += fs-ata_pthru_mod-disk_ata_pthru.lst +PARTMAPFILES += partmap-ata_pthru_mod-disk_ata_pthru.lst + +cmd-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ata_pthru > $@ || (rm -f $@; exit 1) + +fs-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ata_pthru > $@ || (rm -f $@; exit 1) + +partmap-ata_pthru_mod-disk_ata_pthru.lst: disk/ata_pthru.c $(disk/ata_pthru.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ata_pthru_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ata_pthru > $@ || (rm -f $@; exit 1) + + +ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) +ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hdparm.mod. +hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c +CLEANFILES += hdparm.mod mod-hdparm.o mod-hdparm.c pre-hdparm.o hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o und-hdparm.lst +ifneq ($(hdparm_mod_EXPORTS),no) +CLEANFILES += def-hdparm.lst +DEFSYMFILES += def-hdparm.lst +endif +MOSTLYCLEANFILES += hdparm_mod-commands_hdparm.d hdparm_mod-lib_hexdump.d +UNDSYMFILES += und-hdparm.lst + +hdparm.mod: pre-hdparm.o mod-hdparm.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hdparm_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hdparm.o mod-hdparm.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hdparm.o: $(hdparm_mod_DEPENDENCIES) hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o + -rm -f $@ + $(TARGET_CC) $(hdparm_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hdparm_mod-commands_hdparm.o hdparm_mod-lib_hexdump.o + +mod-hdparm.o: mod-hdparm.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -c -o $@ $< + +mod-hdparm.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hdparm' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hdparm_mod_EXPORTS),no) +def-hdparm.lst: pre-hdparm.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hdparm/' > $@ +endif + +und-hdparm.lst: pre-hdparm.o + echo 'hdparm' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hdparm_mod-commands_hdparm.o: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -MD -c -o $@ $< +-include hdparm_mod-commands_hdparm.d + +CLEANFILES += cmd-hdparm_mod-commands_hdparm.lst fs-hdparm_mod-commands_hdparm.lst partmap-hdparm_mod-commands_hdparm.lst +COMMANDFILES += cmd-hdparm_mod-commands_hdparm.lst +FSFILES += fs-hdparm_mod-commands_hdparm.lst +PARTMAPFILES += partmap-hdparm_mod-commands_hdparm.lst + +cmd-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hdparm > $@ || (rm -f $@; exit 1) + +fs-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hdparm > $@ || (rm -f $@; exit 1) + +partmap-hdparm_mod-commands_hdparm.lst: commands/hdparm.c $(commands/hdparm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hdparm > $@ || (rm -f $@; exit 1) + + +hdparm_mod-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -MD -c -o $@ $< +-include hdparm_mod-lib_hexdump.d + +CLEANFILES += cmd-hdparm_mod-lib_hexdump.lst fs-hdparm_mod-lib_hexdump.lst partmap-hdparm_mod-lib_hexdump.lst +COMMANDFILES += cmd-hdparm_mod-lib_hexdump.lst +FSFILES += fs-hdparm_mod-lib_hexdump.lst +PARTMAPFILES += partmap-hdparm_mod-lib_hexdump.lst + +cmd-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hdparm > $@ || (rm -f $@; exit 1) + +fs-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hdparm > $@ || (rm -f $@; exit 1) + +partmap-hdparm_mod-lib_hexdump.lst: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hdparm_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hdparm > $@ || (rm -f $@; exit 1) + + +hdparm_mod_CFLAGS = $(COMMON_CFLAGS) +hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk new file mode 100644 index 0000000..fd66ce9 --- /dev/null +++ b/conf/i386-pc.rmk @@ -0,0 +1,384 @@ +# -*- makefile -*- + +GRUB_MEMORY_MACHINE_LINK_ADDR = 0x8200 + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. +pkglib_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img \ + cdboot.img + +# For boot.img. +boot_img_SOURCES = boot/i386/pc/boot.S +boot_img_ASFLAGS = $(COMMON_ASFLAGS) +boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For pxeboot.img +pxeboot_img_SOURCES = boot/i386/pc/pxeboot.S +pxeboot_img_ASFLAGS = $(COMMON_ASFLAGS) +pxeboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For diskboot.img. +diskboot_img_SOURCES = boot/i386/pc/diskboot.S +diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) +diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,8000 + +# For lnxboot.img. +lnxboot_img_SOURCES = boot/i386/pc/lnxboot.S +lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS) +lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,6000 + +# For cdboot.img. +cdboot_img_SOURCES = boot/i386/pc/cdboot.S +cdboot_img_ASFLAGS = $(COMMON_ASFLAGS) +cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00 + +# For kernel.img. +kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/time.c \ + kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \ + kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/console.c term/i386/vga_common.c \ + symlist.c +kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ + machine/kernel.h machine/pxe.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Utilities. +bin_UTILITIES = grub-mkimage +sbin_UTILITIES = grub-setup grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkimage. +ifeq ($(enable_lzo), yes) +grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ + util/resolve.c +grub_mkimage_LDFLAGS = $(LIBLZO) +else +grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +endif +grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR) +util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-setup. +util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h +grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + partmap/pc.c partmap/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c \ + grub_setup_init.c + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/echo.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/host.c disk/loopback.c disk/scsi.c \ + fs/fshelp.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/main.c normal/color.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +ifeq ($(enable_grub_emu_usb), yes) +grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \ + commands/usbtest.c +grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB) +endif + +# Scripts. +sbin_SCRIPTS = grub-install +bin_SCRIPTS = grub-mkrescue + +# For grub-install. +grub_install_SOURCES = util/i386/pc/grub-install.in + +# For grub-mkrescue. +grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in + +# Modules. +pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \ + _multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod \ + vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ + ata.mod vga.mod memdisk.mod pci.mod lspci.mod \ + aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ + datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \ + usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod + +# For biosdisk.mod. +biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c +biosdisk_mod_CFLAGS = $(COMMON_CFLAGS) +biosdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/i386/pc/chainloader.c +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/i386/pc/chainloader_normal.c +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/pc/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/i386/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/i386/pc/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For serial.mod. +serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod. +_multiboot_mod_SOURCES = loader/i386/pc/multiboot.c \ + loader/i386/pc/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod. +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbe.mod. +vbe_mod_SOURCES = video/i386/pc/vbe.c video/i386/pc/vbeblit.c \ + video/i386/pc/vbefill.c video/i386/pc/vbeutil.c +vbe_mod_CFLAGS = $(COMMON_CFLAGS) +vbe_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbeinfo.mod. +vbeinfo_mod_SOURCES = commands/i386/pc/vbeinfo.c +vbeinfo_mod_CFLAGS = $(COMMON_CFLAGS) +vbeinfo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vbetest.mod. +vbetest_mod_SOURCES = commands/i386/pc/vbetest.c +vbetest_mod_CFLAGS = $(COMMON_CFLAGS) +vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For play.mod. +play_mod_SOURCES = commands/i386/pc/play.c +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata.mod. +ata_mod_SOURCES = disk/ata.c +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For vga.mod. +vga_mod_SOURCES = term/i386/pc/vga.c +vga_mod_CFLAGS = $(COMMON_CFLAGS) +vga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _bsd.mod +_bsd_mod_SOURCES = loader/i386/bsd.c +_bsd_mod_CFLAGS = $(COMMON_CFLAGS) +_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +bsd_mod_SOURCES = loader/i386/bsd_normal.c +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For uhci.mod +uhci_mod_SOURCES = bus/usb/uhci.c +uhci_mod_CFLAGS = $(COMMON_CFLAGS) +uhci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pxe.mod +pxe_mod_SOURCES = fs/i386/pc/pxe.c +pxe_mod_CFLAGS = $(COMMON_CFLAGS) +pxe_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pxecmd.mod +pxecmd_mod_SOURCES = commands/i386/pc/pxecmd.c +pxecmd_mod_CFLAGS = $(COMMON_CFLAGS) +pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/i386/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata_pthru.mod. +ata_pthru_mod_SOURCES = disk/ata_pthru.c +ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) +ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hdparm.mod. +hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c +hdparm_mod_CFLAGS = $(COMMON_CFLAGS) +hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386.mk b/conf/i386.mk new file mode 100644 index 0000000..5cd7b42 --- /dev/null +++ b/conf/i386.mk @@ -0,0 +1,192 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +pkglib_MODULES += cpuid.mod +cpuid_mod_SOURCES = commands/i386/cpuid.c +CLEANFILES += cpuid.mod mod-cpuid.o mod-cpuid.c pre-cpuid.o cpuid_mod-commands_i386_cpuid.o und-cpuid.lst +ifneq ($(cpuid_mod_EXPORTS),no) +CLEANFILES += def-cpuid.lst +DEFSYMFILES += def-cpuid.lst +endif +MOSTLYCLEANFILES += cpuid_mod-commands_i386_cpuid.d +UNDSYMFILES += und-cpuid.lst + +cpuid.mod: pre-cpuid.o mod-cpuid.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cpuid_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cpuid.o mod-cpuid.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cpuid.o: $(cpuid_mod_DEPENDENCIES) cpuid_mod-commands_i386_cpuid.o + -rm -f $@ + $(TARGET_CC) $(cpuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cpuid_mod-commands_i386_cpuid.o + +mod-cpuid.o: mod-cpuid.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -c -o $@ $< + +mod-cpuid.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cpuid' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cpuid_mod_EXPORTS),no) +def-cpuid.lst: pre-cpuid.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cpuid/' > $@ +endif + +und-cpuid.lst: pre-cpuid.o + echo 'cpuid' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cpuid_mod-commands_i386_cpuid.o: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -MD -c -o $@ $< +-include cpuid_mod-commands_i386_cpuid.d + +CLEANFILES += cmd-cpuid_mod-commands_i386_cpuid.lst fs-cpuid_mod-commands_i386_cpuid.lst partmap-cpuid_mod-commands_i386_cpuid.lst +COMMANDFILES += cmd-cpuid_mod-commands_i386_cpuid.lst +FSFILES += fs-cpuid_mod-commands_i386_cpuid.lst +PARTMAPFILES += partmap-cpuid_mod-commands_i386_cpuid.lst + +cmd-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cpuid > $@ || (rm -f $@; exit 1) + +fs-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cpuid > $@ || (rm -f $@; exit 1) + +partmap-cpuid_mod-commands_i386_cpuid.lst: commands/i386/cpuid.c $(commands/i386/cpuid.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/i386 -I$(srcdir)/commands/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cpuid_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cpuid > $@ || (rm -f $@; exit 1) + + +cpuid_mod_CFLAGS = $(COMMON_CFLAGS) +cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += at_keyboard.mod +at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c +CLEANFILES += at_keyboard.mod mod-at_keyboard.o mod-at_keyboard.c pre-at_keyboard.o at_keyboard_mod-term_i386_pc_at_keyboard.o und-at_keyboard.lst +ifneq ($(at_keyboard_mod_EXPORTS),no) +CLEANFILES += def-at_keyboard.lst +DEFSYMFILES += def-at_keyboard.lst +endif +MOSTLYCLEANFILES += at_keyboard_mod-term_i386_pc_at_keyboard.d +UNDSYMFILES += und-at_keyboard.lst + +at_keyboard.mod: pre-at_keyboard.o mod-at_keyboard.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(at_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-at_keyboard.o mod-at_keyboard.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-at_keyboard.o: $(at_keyboard_mod_DEPENDENCIES) at_keyboard_mod-term_i386_pc_at_keyboard.o + -rm -f $@ + $(TARGET_CC) $(at_keyboard_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ at_keyboard_mod-term_i386_pc_at_keyboard.o + +mod-at_keyboard.o: mod-at_keyboard.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -c -o $@ $< + +mod-at_keyboard.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'at_keyboard' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(at_keyboard_mod_EXPORTS),no) +def-at_keyboard.lst: pre-at_keyboard.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 at_keyboard/' > $@ +endif + +und-at_keyboard.lst: pre-at_keyboard.o + echo 'at_keyboard' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +at_keyboard_mod-term_i386_pc_at_keyboard.o: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -MD -c -o $@ $< +-include at_keyboard_mod-term_i386_pc_at_keyboard.d + +CLEANFILES += cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst +COMMANDFILES += cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst +FSFILES += fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst +PARTMAPFILES += partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst + +cmd-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh at_keyboard > $@ || (rm -f $@; exit 1) + +fs-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh at_keyboard > $@ || (rm -f $@; exit 1) + +partmap-at_keyboard_mod-term_i386_pc_at_keyboard.lst: term/i386/pc/at_keyboard.c $(term/i386/pc/at_keyboard.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(at_keyboard_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh at_keyboard > $@ || (rm -f $@; exit 1) + + +at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += vga_text.mod +vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c +CLEANFILES += vga_text.mod mod-vga_text.o mod-vga_text.c pre-vga_text.o vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o und-vga_text.lst +ifneq ($(vga_text_mod_EXPORTS),no) +CLEANFILES += def-vga_text.lst +DEFSYMFILES += def-vga_text.lst +endif +MOSTLYCLEANFILES += vga_text_mod-term_i386_pc_vga_text.d vga_text_mod-term_i386_vga_common.d +UNDSYMFILES += und-vga_text.lst + +vga_text.mod: pre-vga_text.o mod-vga_text.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(vga_text_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-vga_text.o mod-vga_text.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-vga_text.o: $(vga_text_mod_DEPENDENCIES) vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o + -rm -f $@ + $(TARGET_CC) $(vga_text_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ vga_text_mod-term_i386_pc_vga_text.o vga_text_mod-term_i386_vga_common.o + +mod-vga_text.o: mod-vga_text.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -c -o $@ $< + +mod-vga_text.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'vga_text' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(vga_text_mod_EXPORTS),no) +def-vga_text.lst: pre-vga_text.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 vga_text/' > $@ +endif + +und-vga_text.lst: pre-vga_text.o + echo 'vga_text' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +vga_text_mod-term_i386_pc_vga_text.o: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -MD -c -o $@ $< +-include vga_text_mod-term_i386_pc_vga_text.d + +CLEANFILES += cmd-vga_text_mod-term_i386_pc_vga_text.lst fs-vga_text_mod-term_i386_pc_vga_text.lst partmap-vga_text_mod-term_i386_pc_vga_text.lst +COMMANDFILES += cmd-vga_text_mod-term_i386_pc_vga_text.lst +FSFILES += fs-vga_text_mod-term_i386_pc_vga_text.lst +PARTMAPFILES += partmap-vga_text_mod-term_i386_pc_vga_text.lst + +cmd-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vga_text > $@ || (rm -f $@; exit 1) + +fs-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vga_text > $@ || (rm -f $@; exit 1) + +partmap-vga_text_mod-term_i386_pc_vga_text.lst: term/i386/pc/vga_text.c $(term/i386/pc/vga_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386/pc -I$(srcdir)/term/i386/pc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vga_text > $@ || (rm -f $@; exit 1) + + +vga_text_mod-term_i386_vga_common.o: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -MD -c -o $@ $< +-include vga_text_mod-term_i386_vga_common.d + +CLEANFILES += cmd-vga_text_mod-term_i386_vga_common.lst fs-vga_text_mod-term_i386_vga_common.lst partmap-vga_text_mod-term_i386_vga_common.lst +COMMANDFILES += cmd-vga_text_mod-term_i386_vga_common.lst +FSFILES += fs-vga_text_mod-term_i386_vga_common.lst +PARTMAPFILES += partmap-vga_text_mod-term_i386_vga_common.lst + +cmd-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh vga_text > $@ || (rm -f $@; exit 1) + +fs-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh vga_text > $@ || (rm -f $@; exit 1) + +partmap-vga_text_mod-term_i386_vga_common.lst: term/i386/vga_common.c $(term/i386/vga_common.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/i386 -I$(srcdir)/term/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(vga_text_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh vga_text > $@ || (rm -f $@; exit 1) + + +vga_text_mod_CFLAGS = $(COMMON_CFLAGS) +vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386.rmk b/conf/i386.rmk new file mode 100644 index 0000000..93f84ce --- /dev/null +++ b/conf/i386.rmk @@ -0,0 +1,16 @@ +# -*- makefile -*- + +pkglib_MODULES += cpuid.mod +cpuid_mod_SOURCES = commands/i386/cpuid.c +cpuid_mod_CFLAGS = $(COMMON_CFLAGS) +cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += at_keyboard.mod +at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c +at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += vga_text.mod +vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c +vga_text_mod_CFLAGS = $(COMMON_CFLAGS) +vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/powerpc-ieee1275.mk b/conf/powerpc-ieee1275.mk new file mode 100644 index 0000000..18edeaf --- /dev/null +++ b/conf/powerpc-ieee1275.mk @@ -0,0 +1,1542 @@ + +# Generated by genmk.rb, please don't edit! +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__ +COMMON_CFLAGS = -ffreestanding +COMMON_LDFLAGS += -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \ + symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ + pc_partition.h ieee1275/ieee1275.h machine/kernel.h + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Programs +pkglib_PROGRAMS = kernel.elf + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c +CLEANFILES += grub-mkdevicemap$(EXEEXT) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o +MOSTLYCLEANFILES += grub_mkdevicemap-util_grub_mkdevicemap.d grub_mkdevicemap-util_misc.d + +grub-mkdevicemap: $(grub_mkdevicemap_DEPENDENCIES) grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o + $(CC) -o $@ grub_mkdevicemap-util_grub_mkdevicemap.o grub_mkdevicemap-util_misc.o $(LDFLAGS) $(grub_mkdevicemap_LDFLAGS) + +grub_mkdevicemap-util_grub_mkdevicemap.o: util/grub-mkdevicemap.c $(util/grub-mkdevicemap.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_grub_mkdevicemap.d + +grub_mkdevicemap-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkdevicemap_CFLAGS) -MD -c -o $@ $< +-include grub_mkdevicemap-util_misc.d + + +# For grub-emu +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/search.c commands/terminal.c commands/test.c \ + commands/ls.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/halt.c commands/reboot.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c kern/file.c kern/fs.c kern/loader.c kern/main.c \ + kern/misc.c kern/parser.c kern/partition.c kern/rescue.c \ + kern/term.c fs/fshelp.c \ + normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/menu_entry.c normal/menu_viewer.c normal/misc.c \ + normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/powerpc/ieee1275/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_script.tab.c grub_emu_init.c +CLEANFILES += grub-emu$(EXEEXT) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-fs_fshelp.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o +MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d grub_emu-commands_cmp.d grub_emu-commands_configfile.d grub_emu-commands_help.d grub_emu-commands_search.d grub_emu-commands_terminal.d grub_emu-commands_test.d grub_emu-commands_ls.d grub_emu-commands_blocklist.d grub_emu-commands_hexdump.d grub_emu-lib_hexdump.d grub_emu-commands_halt.d grub_emu-commands_reboot.d grub_emu-disk_loopback.d grub_emu-fs_affs.d grub_emu-fs_cpio.d grub_emu-fs_ext2.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_hfs.d grub_emu-fs_hfsplus.d grub_emu-fs_iso9660.d grub_emu-fs_udf.d grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ntfs.d grub_emu-fs_ntfscomp.d grub_emu-fs_reiserfs.d grub_emu-fs_sfs.d grub_emu-fs_ufs.d grub_emu-fs_xfs.d grub_emu-fs_afs.d grub_emu-fs_tar.d grub_emu-io_gzio.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_elf.d grub_emu-kern_env.d grub_emu-kern_err.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_parser.d grub_emu-kern_partition.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-fs_fshelp.d grub_emu-normal_arg.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_completion.d grub_emu-normal_execute.d grub_emu-normal_function.d grub_emu-normal_lexer.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_text.d grub_emu-normal_menu_entry.d grub_emu-normal_menu_viewer.d grub_emu-normal_misc.d grub_emu-normal_script.d grub_emu-normal_color.d grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d grub_emu-partmap_sun.d grub_emu-partmap_acorn.d grub_emu-util_console.d grub_emu-util_hostfs.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_hostdisk.d grub_emu-util_getroot.d grub_emu-util_powerpc_ieee1275_misc.d grub_emu-disk_raid.d grub_emu-disk_raid5_recover.d grub_emu-disk_raid6_recover.d grub_emu-disk_mdraid_linux.d grub_emu-disk_dmraid_nvidia.d grub_emu-disk_lvm.d grub_emu-grub_script_tab.d grub_emu-grub_emu_init.d + +grub-emu: $(grub_emu_DEPENDENCIES) grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-fs_fshelp.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o + $(CC) -o $@ grub_emu-commands_boot.o grub_emu-commands_cat.o grub_emu-commands_cmp.o grub_emu-commands_configfile.o grub_emu-commands_help.o grub_emu-commands_search.o grub_emu-commands_terminal.o grub_emu-commands_test.o grub_emu-commands_ls.o grub_emu-commands_blocklist.o grub_emu-commands_hexdump.o grub_emu-lib_hexdump.o grub_emu-commands_halt.o grub_emu-commands_reboot.o grub_emu-disk_loopback.o grub_emu-fs_affs.o grub_emu-fs_cpio.o grub_emu-fs_ext2.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_hfs.o grub_emu-fs_hfsplus.o grub_emu-fs_iso9660.o grub_emu-fs_udf.o grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ntfs.o grub_emu-fs_ntfscomp.o grub_emu-fs_reiserfs.o grub_emu-fs_sfs.o grub_emu-fs_ufs.o grub_emu-fs_xfs.o grub_emu-fs_afs.o grub_emu-fs_tar.o grub_emu-io_gzio.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_elf.o grub_emu-kern_env.o grub_emu-kern_err.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_parser.o grub_emu-kern_partition.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-fs_fshelp.o grub_emu-normal_arg.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_completion.o grub_emu-normal_execute.o grub_emu-normal_function.o grub_emu-normal_lexer.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_text.o grub_emu-normal_menu_entry.o grub_emu-normal_menu_viewer.o grub_emu-normal_misc.o grub_emu-normal_script.o grub_emu-normal_color.o grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o grub_emu-partmap_sun.o grub_emu-partmap_acorn.o grub_emu-util_console.o grub_emu-util_hostfs.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_hostdisk.o grub_emu-util_getroot.o grub_emu-util_powerpc_ieee1275_misc.o grub_emu-disk_raid.o grub_emu-disk_raid5_recover.o grub_emu-disk_raid6_recover.o grub_emu-disk_mdraid_linux.o grub_emu-disk_dmraid_nvidia.o grub_emu-disk_lvm.o grub_emu-grub_script_tab.o grub_emu-grub_emu_init.o $(LDFLAGS) $(grub_emu_LDFLAGS) + +grub_emu-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_boot.d + +grub_emu-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cat.d + +grub_emu-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_cmp.d + +grub_emu-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_configfile.d + +grub_emu-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_help.d + +grub_emu-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_search.d + +grub_emu-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_terminal.d + +grub_emu-commands_test.o: commands/test.c $(commands/test.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_test.d + +grub_emu-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_ls.d + +grub_emu-commands_blocklist.o: commands/blocklist.c $(commands/blocklist.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_blocklist.d + +grub_emu-commands_hexdump.o: commands/hexdump.c $(commands/hexdump.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_hexdump.d + +grub_emu-lib_hexdump.o: lib/hexdump.c $(lib/hexdump.c_DEPENDENCIES) + $(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-lib_hexdump.d + +grub_emu-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_halt.d + +grub_emu-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-commands_reboot.d + +grub_emu-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_loopback.d + +grub_emu-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_affs.d + +grub_emu-fs_cpio.o: fs/cpio.c $(fs/cpio.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_cpio.d + +grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ext2.d + +grub_emu-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fat.d + +grub_emu-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ext2.d + +grub_emu-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfs.d + +grub_emu-fs_hfsplus.o: fs/hfsplus.c $(fs/hfsplus.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_hfsplus.d + +grub_emu-fs_iso9660.o: fs/iso9660.c $(fs/iso9660.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_iso9660.d + +grub_emu-fs_udf.o: fs/udf.c $(fs/udf.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_udf.d + +grub_emu-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_jfs.d + +grub_emu-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_minix.d + +grub_emu-fs_ntfs.o: fs/ntfs.c $(fs/ntfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfs.d + +grub_emu-fs_ntfscomp.o: fs/ntfscomp.c $(fs/ntfscomp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ntfscomp.d + +grub_emu-fs_reiserfs.o: fs/reiserfs.c $(fs/reiserfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_reiserfs.d + +grub_emu-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_sfs.d + +grub_emu-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_ufs.d + +grub_emu-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_xfs.d + +grub_emu-fs_afs.o: fs/afs.c $(fs/afs.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_afs.d + +grub_emu-fs_tar.o: fs/tar.c $(fs/tar.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_tar.d + +grub_emu-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(CC) -Iio -I$(srcdir)/io $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-io_gzio.d + +grub_emu-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_device.d + +grub_emu-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_disk.d + +grub_emu-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_dl.d + +grub_emu-kern_elf.o: kern/elf.c $(kern/elf.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_elf.d + +grub_emu-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_env.d + +grub_emu-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_err.d + +grub_emu-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_file.d + +grub_emu-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_fs.d + +grub_emu-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_loader.d + +grub_emu-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_main.d + +grub_emu-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_misc.d + +grub_emu-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_parser.d + +grub_emu-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_partition.d + +grub_emu-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_rescue.d + +grub_emu-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(CC) -Ikern -I$(srcdir)/kern $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-kern_term.d + +grub_emu-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-fs_fshelp.d + +grub_emu-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_arg.d + +grub_emu-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_cmdline.d + +grub_emu-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_command.d + +grub_emu-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_completion.d + +grub_emu-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_execute.d + +grub_emu-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_function.d + +grub_emu-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_lexer.d + +grub_emu-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_main.d + +grub_emu-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu.d + +grub_emu-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_text.d + +grub_emu-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_entry.d + +grub_emu-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_menu_viewer.d + +grub_emu-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_misc.d + +grub_emu-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_script.d + +grub_emu-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-normal_color.d + +grub_emu-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_amiga.d + +grub_emu-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_apple.d + +grub_emu-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_pc.d + +grub_emu-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_sun.d + +grub_emu-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(CC) -Ipartmap -I$(srcdir)/partmap $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-partmap_acorn.d + +grub_emu-util_console.o: util/console.c $(util/console.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_console.d + +grub_emu-util_hostfs.o: util/hostfs.c $(util/hostfs.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostfs.d + +grub_emu-util_grub_emu.o: util/grub-emu.c $(util/grub-emu.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_grub_emu.d + +grub_emu-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_misc.d + +grub_emu-util_hostdisk.o: util/hostdisk.c $(util/hostdisk.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_hostdisk.d + +grub_emu-util_getroot.o: util/getroot.c $(util/getroot.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_getroot.d + +grub_emu-util_powerpc_ieee1275_misc.o: util/powerpc/ieee1275/misc.c $(util/powerpc/ieee1275/misc.c_DEPENDENCIES) + $(CC) -Iutil/powerpc/ieee1275 -I$(srcdir)/util/powerpc/ieee1275 $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-util_powerpc_ieee1275_misc.d + +grub_emu-disk_raid.o: disk/raid.c $(disk/raid.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid.d + +grub_emu-disk_raid5_recover.o: disk/raid5_recover.c $(disk/raid5_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid5_recover.d + +grub_emu-disk_raid6_recover.o: disk/raid6_recover.c $(disk/raid6_recover.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_raid6_recover.d + +grub_emu-disk_mdraid_linux.o: disk/mdraid_linux.c $(disk/mdraid_linux.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_mdraid_linux.d + +grub_emu-disk_dmraid_nvidia.o: disk/dmraid_nvidia.c $(disk/dmraid_nvidia.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_dmraid_nvidia.d + +grub_emu-disk_lvm.o: disk/lvm.c $(disk/lvm.c_DEPENDENCIES) + $(CC) -Idisk -I$(srcdir)/disk $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-disk_lvm.d + +grub_emu-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_script_tab.d + +grub_emu-grub_emu_init.o: grub_emu_init.c $(grub_emu_init.c_DEPENDENCIES) + $(CC) -I. -I$(srcdir)/. $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $< +-include grub_emu-grub_emu_init.d + + +grub_emu_LDFLAGS = $(LIBCURSES) + +kernel_elf_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ + kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/ieee1275/init.c \ + kern/ieee1275/mmap.c \ + term/ieee1275/ofconsole.c \ + kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ + kern/parser.c kern/partition.c kern/env.c kern/powerpc/dl.c \ + kern/generic/millisleep.c kern/time.c \ + symlist.c kern/powerpc/cache.S +CLEANFILES += kernel.elf kernel_elf-kern_powerpc_ieee1275_startup.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_time.o kernel_elf-symlist.o kernel_elf-kern_powerpc_cache.o +MOSTLYCLEANFILES += kernel_elf-kern_powerpc_ieee1275_startup.d kernel_elf-kern_ieee1275_cmain.d kernel_elf-kern_ieee1275_ieee1275.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_err.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-kern_ieee1275_init.d kernel_elf-kern_ieee1275_mmap.d kernel_elf-term_ieee1275_ofconsole.d kernel_elf-kern_ieee1275_openfw.d kernel_elf-disk_ieee1275_ofdisk.d kernel_elf-kern_parser.d kernel_elf-kern_partition.d kernel_elf-kern_env.d kernel_elf-kern_powerpc_dl.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_time.d kernel_elf-symlist.d kernel_elf-kern_powerpc_cache.d + +kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_powerpc_ieee1275_startup.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_time.o kernel_elf-symlist.o kernel_elf-kern_powerpc_cache.o + $(TARGET_CC) -o $@ kernel_elf-kern_powerpc_ieee1275_startup.o kernel_elf-kern_ieee1275_cmain.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_err.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-kern_ieee1275_init.o kernel_elf-kern_ieee1275_mmap.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_parser.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_powerpc_dl.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_time.o kernel_elf-symlist.o kernel_elf-kern_powerpc_cache.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) + +kernel_elf-kern_powerpc_ieee1275_startup.o: kern/powerpc/ieee1275/startup.S $(kern/powerpc/ieee1275/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/powerpc/ieee1275 -I$(srcdir)/kern/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_powerpc_ieee1275_startup.d + +kernel_elf-kern_ieee1275_cmain.o: kern/ieee1275/cmain.c $(kern/ieee1275/cmain.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_cmain.d + +kernel_elf-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_ieee1275.d + +kernel_elf-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_main.d + +kernel_elf-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_device.d + +kernel_elf-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_disk.d + +kernel_elf-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_dl.d + +kernel_elf-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_err.d + +kernel_elf-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_file.d + +kernel_elf-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_fs.d + +kernel_elf-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_misc.d + +kernel_elf-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_mm.d + +kernel_elf-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_loader.d + +kernel_elf-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_rescue.d + +kernel_elf-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_term.d + +kernel_elf-kern_ieee1275_init.o: kern/ieee1275/init.c $(kern/ieee1275/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_init.d + +kernel_elf-kern_ieee1275_mmap.o: kern/ieee1275/mmap.c $(kern/ieee1275/mmap.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_mmap.d + +kernel_elf-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_ieee1275_ofconsole.d + +kernel_elf-kern_ieee1275_openfw.o: kern/ieee1275/openfw.c $(kern/ieee1275/openfw.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_openfw.d + +kernel_elf-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-disk_ieee1275_ofdisk.d + +kernel_elf-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_parser.d + +kernel_elf-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_partition.d + +kernel_elf-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_env.d + +kernel_elf-kern_powerpc_dl.o: kern/powerpc/dl.c $(kern/powerpc/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/powerpc -I$(srcdir)/kern/powerpc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_powerpc_dl.d + +kernel_elf-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_millisleep.d + +kernel_elf-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_time.d + +kernel_elf-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-symlist.d + +kernel_elf-kern_powerpc_cache.o: kern/powerpc/cache.S $(kern/powerpc/cache.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/powerpc -I$(srcdir)/kern/powerpc $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_powerpc_cache.d + +kernel_elf_HEADERS = grub/powerpc/ieee1275/ieee1275.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,0x200000,-Bstatic + +# Scripts. +sbin_SCRIPTS = grub-install +bin_SCRIPTS = grub-mkrescue + +# For grub-install. +grub_install_SOURCES = util/ieee1275/grub-install.in +CLEANFILES += grub-install + +grub-install: util/ieee1275/grub-install.in $(util/ieee1275/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/ieee1275/grub-install.in + chmod +x $@ + + +# For grub-mkrescue. +grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in +CLEANFILES += grub-mkrescue + +grub-mkrescue: util/powerpc/ieee1275/grub-mkrescue.in $(util/powerpc/ieee1275/grub-mkrescue.in_DEPENDENCIES) config.status + ./config.status --file=grub-mkrescue:util/powerpc/ieee1275/grub-mkrescue.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = halt.mod \ + _linux.mod \ + linux.mod \ + normal.mod \ + reboot.mod \ + suspend.mod \ + _multiboot.mod \ + multiboot.mod \ + memdisk.mod \ + lsmmap.mod + +# For _linux.mod. +_linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_powerpc_ieee1275_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_powerpc_ieee1275_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_powerpc_ieee1275_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_powerpc_ieee1275_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_powerpc_ieee1275_linux.o: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_powerpc_ieee1275_linux.d + +CLEANFILES += cmd-_linux_mod-loader_powerpc_ieee1275_linux.lst fs-_linux_mod-loader_powerpc_ieee1275_linux.lst partmap-_linux_mod-loader_powerpc_ieee1275_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_powerpc_ieee1275_linux.lst +FSFILES += fs-_linux_mod-loader_powerpc_ieee1275_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_powerpc_ieee1275_linux.lst + +cmd-_linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_powerpc_ieee1275_linux.lst: loader/powerpc/ieee1275/linux.c $(loader/powerpc/ieee1275/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/powerpc/ieee1275/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_powerpc_ieee1275_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_powerpc_ieee1275_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_powerpc_ieee1275_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_powerpc_ieee1275_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_powerpc_ieee1275_linux_normal.o: loader/powerpc/ieee1275/linux_normal.c $(loader/powerpc/ieee1275/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_powerpc_ieee1275_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_powerpc_ieee1275_linux_normal.lst fs-linux_mod-loader_powerpc_ieee1275_linux_normal.lst partmap-linux_mod-loader_powerpc_ieee1275_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_powerpc_ieee1275_linux_normal.lst +FSFILES += fs-linux_mod-loader_powerpc_ieee1275_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_powerpc_ieee1275_linux_normal.lst + +cmd-linux_mod-loader_powerpc_ieee1275_linux_normal.lst: loader/powerpc/ieee1275/linux_normal.c $(loader/powerpc/ieee1275/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_powerpc_ieee1275_linux_normal.lst: loader/powerpc/ieee1275/linux_normal.c $(loader/powerpc/ieee1275/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_powerpc_ieee1275_linux_normal.lst: loader/powerpc/ieee1275/linux_normal.c $(loader/powerpc/ieee1275/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/powerpc/ieee1275 -I$(srcdir)/loader/powerpc/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/powerpc/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_powerpc_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_powerpc_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_powerpc_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_powerpc_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_powerpc_setjmp.o: normal/powerpc/setjmp.S $(normal/powerpc/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/powerpc -I$(srcdir)/normal/powerpc $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_powerpc_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_powerpc_setjmp.lst fs-normal_mod-normal_powerpc_setjmp.lst partmap-normal_mod-normal_powerpc_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_powerpc_setjmp.lst +FSFILES += fs-normal_mod-normal_powerpc_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_powerpc_setjmp.lst + +cmd-normal_mod-normal_powerpc_setjmp.lst: normal/powerpc/setjmp.S $(normal/powerpc/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/powerpc -I$(srcdir)/normal/powerpc $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_powerpc_setjmp.lst: normal/powerpc/setjmp.S $(normal/powerpc/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/powerpc -I$(srcdir)/normal/powerpc $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_powerpc_setjmp.lst: normal/powerpc/setjmp.S $(normal/powerpc/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/powerpc -I$(srcdir)/normal/powerpc $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +CLEANFILES += suspend.mod mod-suspend.o mod-suspend.c pre-suspend.o suspend_mod-commands_ieee1275_suspend.o und-suspend.lst +ifneq ($(suspend_mod_EXPORTS),no) +CLEANFILES += def-suspend.lst +DEFSYMFILES += def-suspend.lst +endif +MOSTLYCLEANFILES += suspend_mod-commands_ieee1275_suspend.d +UNDSYMFILES += und-suspend.lst + +suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-suspend.o mod-suspend.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-suspend.o: $(suspend_mod_DEPENDENCIES) suspend_mod-commands_ieee1275_suspend.o + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ suspend_mod-commands_ieee1275_suspend.o + +mod-suspend.o: mod-suspend.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -c -o $@ $< + +mod-suspend.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'suspend' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(suspend_mod_EXPORTS),no) +def-suspend.lst: pre-suspend.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 suspend/' > $@ +endif + +und-suspend.lst: pre-suspend.o + echo 'suspend' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +suspend_mod-commands_ieee1275_suspend.o: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -MD -c -o $@ $< +-include suspend_mod-commands_ieee1275_suspend.d + +CLEANFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst fs-suspend_mod-commands_ieee1275_suspend.lst partmap-suspend_mod-commands_ieee1275_suspend.lst +COMMANDFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst +FSFILES += fs-suspend_mod-commands_ieee1275_suspend.lst +PARTMAPFILES += partmap-suspend_mod-commands_ieee1275_suspend.lst + +cmd-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh suspend > $@ || (rm -f $@; exit 1) + +fs-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh suspend > $@ || (rm -f $@; exit 1) + +partmap-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh suspend > $@ || (rm -f $@; exit 1) + + +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod +_multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +CLEANFILES += _multiboot.mod mod-_multiboot.o mod-_multiboot.c pre-_multiboot.o _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o und-_multiboot.lst +ifneq ($(_multiboot_mod_EXPORTS),no) +CLEANFILES += def-_multiboot.lst +DEFSYMFILES += def-_multiboot.lst +endif +MOSTLYCLEANFILES += _multiboot_mod-loader_ieee1275_multiboot2.d _multiboot_mod-loader_multiboot2.d _multiboot_mod-loader_multiboot_loader.d +UNDSYMFILES += und-_multiboot.lst + +_multiboot.mod: pre-_multiboot.o mod-_multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_multiboot.o mod-_multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_multiboot.o: $(_multiboot_mod_DEPENDENCIES) _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + -rm -f $@ + $(TARGET_CC) $(_multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _multiboot_mod-loader_ieee1275_multiboot2.o _multiboot_mod-loader_multiboot2.o _multiboot_mod-loader_multiboot_loader.o + +mod-_multiboot.o: mod-_multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -c -o $@ $< + +mod-_multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_multiboot_mod_EXPORTS),no) +def-_multiboot.lst: pre-_multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _multiboot/' > $@ +endif + +und-_multiboot.lst: pre-_multiboot.o + echo '_multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_multiboot_mod-loader_ieee1275_multiboot2.o: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_ieee1275_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst fs-_multiboot_mod-loader_ieee1275_multiboot2.lst partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_ieee1275_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst + +cmd-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_ieee1275_multiboot2.lst: loader/ieee1275/multiboot2.c $(loader/ieee1275/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/ieee1275 -I$(srcdir)/loader/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot2.o: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot2.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot2.lst fs-_multiboot_mod-loader_multiboot2.lst partmap-_multiboot_mod-loader_multiboot2.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot2.lst +FSFILES += fs-_multiboot_mod-loader_multiboot2.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot2.lst + +cmd-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot2.lst: loader/multiboot2.c $(loader/multiboot2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod-loader_multiboot_loader.o: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include _multiboot_mod-loader_multiboot_loader.d + +CLEANFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst fs-_multiboot_mod-loader_multiboot_loader.lst partmap-_multiboot_mod-loader_multiboot_loader.lst +COMMANDFILES += cmd-_multiboot_mod-loader_multiboot_loader.lst +FSFILES += fs-_multiboot_mod-loader_multiboot_loader.lst +PARTMAPFILES += partmap-_multiboot_mod-loader_multiboot_loader.lst + +cmd-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _multiboot > $@ || (rm -f $@; exit 1) + +fs-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _multiboot > $@ || (rm -f $@; exit 1) + +partmap-_multiboot_mod-loader_multiboot_loader.lst: loader/multiboot_loader.c $(loader/multiboot_loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _multiboot > $@ || (rm -f $@; exit 1) + + +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +CLEANFILES += multiboot.mod mod-multiboot.o mod-multiboot.c pre-multiboot.o multiboot_mod-loader_multiboot_loader_normal.o und-multiboot.lst +ifneq ($(multiboot_mod_EXPORTS),no) +CLEANFILES += def-multiboot.lst +DEFSYMFILES += def-multiboot.lst +endif +MOSTLYCLEANFILES += multiboot_mod-loader_multiboot_loader_normal.d +UNDSYMFILES += und-multiboot.lst + +multiboot.mod: pre-multiboot.o mod-multiboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-multiboot.o mod-multiboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-multiboot.o: $(multiboot_mod_DEPENDENCIES) multiboot_mod-loader_multiboot_loader_normal.o + -rm -f $@ + $(TARGET_CC) $(multiboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ multiboot_mod-loader_multiboot_loader_normal.o + +mod-multiboot.o: mod-multiboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -c -o $@ $< + +mod-multiboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'multiboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(multiboot_mod_EXPORTS),no) +def-multiboot.lst: pre-multiboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 multiboot/' > $@ +endif + +und-multiboot.lst: pre-multiboot.o + echo 'multiboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +multiboot_mod-loader_multiboot_loader_normal.o: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -MD -c -o $@ $< +-include multiboot_mod-loader_multiboot_loader_normal.d + +CLEANFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst fs-multiboot_mod-loader_multiboot_loader_normal.lst partmap-multiboot_mod-loader_multiboot_loader_normal.lst +COMMANDFILES += cmd-multiboot_mod-loader_multiboot_loader_normal.lst +FSFILES += fs-multiboot_mod-loader_multiboot_loader_normal.lst +PARTMAPFILES += partmap-multiboot_mod-loader_multiboot_loader_normal.lst + +cmd-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh multiboot > $@ || (rm -f $@; exit 1) + +fs-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh multiboot > $@ || (rm -f $@; exit 1) + +partmap-multiboot_mod-loader_multiboot_loader_normal.lst: loader/multiboot_loader_normal.c $(loader/multiboot_loader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(multiboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh multiboot > $@ || (rm -f $@; exit 1) + + +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +CLEANFILES += memdisk.mod mod-memdisk.o mod-memdisk.c pre-memdisk.o memdisk_mod-disk_memdisk.o und-memdisk.lst +ifneq ($(memdisk_mod_EXPORTS),no) +CLEANFILES += def-memdisk.lst +DEFSYMFILES += def-memdisk.lst +endif +MOSTLYCLEANFILES += memdisk_mod-disk_memdisk.d +UNDSYMFILES += und-memdisk.lst + +memdisk.mod: pre-memdisk.o mod-memdisk.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-memdisk.o mod-memdisk.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-memdisk.o: $(memdisk_mod_DEPENDENCIES) memdisk_mod-disk_memdisk.o + -rm -f $@ + $(TARGET_CC) $(memdisk_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ memdisk_mod-disk_memdisk.o + +mod-memdisk.o: mod-memdisk.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -c -o $@ $< + +mod-memdisk.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'memdisk' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(memdisk_mod_EXPORTS),no) +def-memdisk.lst: pre-memdisk.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 memdisk/' > $@ +endif + +und-memdisk.lst: pre-memdisk.o + echo 'memdisk' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +memdisk_mod-disk_memdisk.o: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -MD -c -o $@ $< +-include memdisk_mod-disk_memdisk.d + +CLEANFILES += cmd-memdisk_mod-disk_memdisk.lst fs-memdisk_mod-disk_memdisk.lst partmap-memdisk_mod-disk_memdisk.lst +COMMANDFILES += cmd-memdisk_mod-disk_memdisk.lst +FSFILES += fs-memdisk_mod-disk_memdisk.lst +PARTMAPFILES += partmap-memdisk_mod-disk_memdisk.lst + +cmd-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh memdisk > $@ || (rm -f $@; exit 1) + +fs-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh memdisk > $@ || (rm -f $@; exit 1) + +partmap-memdisk_mod-disk_memdisk.lst: disk/memdisk.c $(disk/memdisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(memdisk_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh memdisk > $@ || (rm -f $@; exit 1) + + +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +CLEANFILES += lsmmap.mod mod-lsmmap.o mod-lsmmap.c pre-lsmmap.o lsmmap_mod-commands_lsmmap.o und-lsmmap.lst +ifneq ($(lsmmap_mod_EXPORTS),no) +CLEANFILES += def-lsmmap.lst +DEFSYMFILES += def-lsmmap.lst +endif +MOSTLYCLEANFILES += lsmmap_mod-commands_lsmmap.d +UNDSYMFILES += und-lsmmap.lst + +lsmmap.mod: pre-lsmmap.o mod-lsmmap.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lsmmap.o mod-lsmmap.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lsmmap.o: $(lsmmap_mod_DEPENDENCIES) lsmmap_mod-commands_lsmmap.o + -rm -f $@ + $(TARGET_CC) $(lsmmap_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lsmmap_mod-commands_lsmmap.o + +mod-lsmmap.o: mod-lsmmap.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -c -o $@ $< + +mod-lsmmap.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lsmmap' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lsmmap_mod_EXPORTS),no) +def-lsmmap.lst: pre-lsmmap.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lsmmap/' > $@ +endif + +und-lsmmap.lst: pre-lsmmap.o + echo 'lsmmap' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lsmmap_mod-commands_lsmmap.o: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -MD -c -o $@ $< +-include lsmmap_mod-commands_lsmmap.d + +CLEANFILES += cmd-lsmmap_mod-commands_lsmmap.lst fs-lsmmap_mod-commands_lsmmap.lst partmap-lsmmap_mod-commands_lsmmap.lst +COMMANDFILES += cmd-lsmmap_mod-commands_lsmmap.lst +FSFILES += fs-lsmmap_mod-commands_lsmmap.lst +PARTMAPFILES += partmap-lsmmap_mod-commands_lsmmap.lst + +cmd-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lsmmap > $@ || (rm -f $@; exit 1) + +fs-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lsmmap > $@ || (rm -f $@; exit 1) + +partmap-lsmmap_mod-commands_lsmmap.lst: commands/lsmmap.c $(commands/lsmmap.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lsmmap_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lsmmap > $@ || (rm -f $@; exit 1) + + +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/common.mk + diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk new file mode 100644 index 0000000..51e7c07 --- /dev/null +++ b/conf/powerpc-ieee1275.rmk @@ -0,0 +1,185 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__ +COMMON_CFLAGS = -ffreestanding +COMMON_LDFLAGS += -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \ + symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ + pc_partition.h ieee1275/ieee1275.h machine/kernel.h + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Programs +pkglib_PROGRAMS = kernel.elf + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/search.c commands/terminal.c commands/test.c \ + commands/ls.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/halt.c commands/reboot.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c fs/tar.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c kern/file.c kern/fs.c kern/loader.c kern/main.c \ + kern/misc.c kern/parser.c kern/partition.c kern/rescue.c \ + kern/term.c fs/fshelp.c \ + normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/menu_entry.c normal/menu_viewer.c normal/misc.c \ + normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/powerpc/ieee1275/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_script.tab.c grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +kernel_elf_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ + kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/ieee1275/init.c \ + kern/ieee1275/mmap.c \ + term/ieee1275/ofconsole.c \ + kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ + kern/parser.c kern/partition.c kern/env.c kern/powerpc/dl.c \ + kern/generic/millisleep.c kern/time.c \ + symlist.c kern/powerpc/cache.S +kernel_elf_HEADERS = grub/powerpc/ieee1275/ieee1275.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,0x200000,-Bstatic + +# Scripts. +sbin_SCRIPTS = grub-install +bin_SCRIPTS = grub-mkrescue + +# For grub-install. +grub_install_SOURCES = util/ieee1275/grub-install.in + +# For grub-mkrescue. +grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in + +# Modules. +pkglib_MODULES = halt.mod \ + _linux.mod \ + linux.mod \ + normal.mod \ + reboot.mod \ + suspend.mod \ + _multiboot.mod \ + multiboot.mod \ + memdisk.mod \ + lsmmap.mod + +# For _linux.mod. +_linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/powerpc/ieee1275/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/powerpc/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _multiboot.mod +_multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ + loader/multiboot2.c \ + loader/multiboot_loader.c +_multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +_multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For multiboot.mod +multiboot_mod_SOURCES = loader/multiboot_loader_normal.c +multiboot_mod_CFLAGS = $(COMMON_CFLAGS) +multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/common.mk + diff --git a/conf/sparc64-ieee1275.mk b/conf/sparc64-ieee1275.mk new file mode 100644 index 0000000..ce49690 --- /dev/null +++ b/conf/sparc64-ieee1275.mk @@ -0,0 +1,2315 @@ + +# Generated by genmk.rb, please don't edit! +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc +COMMON_CFLAGS = -ggdb -ffreestanding -m64 -mno-app-regs +COMMON_LDFLAGS = -melf64_sparc -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \ + symbol.h term.h time.h types.h sparc64/libgcc.h loader.h partition.h \ + pc_partition.h ieee1275/ieee1275.h machine/kernel.h + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# For the parser. +grub_script.tab.c grub_script.tab.h: normal/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Programs +pkglib_PROGRAMS = kernel.elf + +# Utilities. +#bin_UTILITIES = grub-mkimage +#ifeq ($(enable_grub_emu), yes) +#bin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \ + util/resolve.c + +# For grub-emu +#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ +# commands/configfile.c commands/default.c commands/help.c \ +# commands/search.c commands/terminal.c commands/ls.c \ +# commands/timeout.c commands/test.c \ +# commands/halt.c commands/reboot.c \ +# disk/loopback.c \ +# fs/affs.c fs/fat.c fs/ext2.c fs/fshelp.c fs/hfs.c fs/iso9660.c \ +# fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c \ +# grub_script.tab.c \ +# io/gzio.c \ +# kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c \ +# kern/file.c kern/fs.c kern/loader.c kern/main.c kern/misc.c \ +# kern/parser.c kern/partition.c kern/rescue.c kern/term.c \ +# normal/arg.c normal/cmdline.c normal/command.c \ +# normal/completion.c normal/context.c normal/execute.c \ +# normal/function.c normal/lexer.c \ +# normal/main.c normal/menu.c normal/menu_entry.c \ +# normal/menu_text.c \ +# normal/menu_viewer.c normal/misc.c \ +# partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ +# partmap/acorn.c \ +# util/console.c util/grub-emu.c util/misc.c \ +# util/hostdisk.c util/getroot.c \ +# util/sparc64/ieee1275/misc.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \ + kern/main.c kern/device.c kern/disk.c kern/dl.c kern/file.c \ + kern/fs.c kern/err.c kern/misc.c kern/mm.c kern/loader.c \ + kern/rescue.c kern/term.c term/ieee1275/ofconsole.c \ + kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ + kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \ + kern/generic/millisleep.c kern/generic/get_time_ms.c \ + kern/sparc64/cache.S kern/parser.c +CLEANFILES += kernel.elf kernel_elf-kern_sparc64_ieee1275_init.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_sparc64_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_sparc64_dl.o kernel_elf-symlist.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_generic_get_time_ms.o kernel_elf-kern_sparc64_cache.o kernel_elf-kern_parser.o +MOSTLYCLEANFILES += kernel_elf-kern_sparc64_ieee1275_init.d kernel_elf-kern_ieee1275_ieee1275.d kernel_elf-kern_main.d kernel_elf-kern_device.d kernel_elf-kern_disk.d kernel_elf-kern_dl.d kernel_elf-kern_file.d kernel_elf-kern_fs.d kernel_elf-kern_err.d kernel_elf-kern_misc.d kernel_elf-kern_mm.d kernel_elf-kern_loader.d kernel_elf-kern_rescue.d kernel_elf-kern_term.d kernel_elf-term_ieee1275_ofconsole.d kernel_elf-kern_sparc64_ieee1275_openfw.d kernel_elf-disk_ieee1275_ofdisk.d kernel_elf-kern_partition.d kernel_elf-kern_env.d kernel_elf-kern_sparc64_dl.d kernel_elf-symlist.d kernel_elf-kern_generic_millisleep.d kernel_elf-kern_generic_get_time_ms.d kernel_elf-kern_sparc64_cache.d kernel_elf-kern_parser.d + +kernel.elf: $(kernel_elf_DEPENDENCIES) kernel_elf-kern_sparc64_ieee1275_init.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_sparc64_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_sparc64_dl.o kernel_elf-symlist.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_generic_get_time_ms.o kernel_elf-kern_sparc64_cache.o kernel_elf-kern_parser.o + $(TARGET_CC) -o $@ kernel_elf-kern_sparc64_ieee1275_init.o kernel_elf-kern_ieee1275_ieee1275.o kernel_elf-kern_main.o kernel_elf-kern_device.o kernel_elf-kern_disk.o kernel_elf-kern_dl.o kernel_elf-kern_file.o kernel_elf-kern_fs.o kernel_elf-kern_err.o kernel_elf-kern_misc.o kernel_elf-kern_mm.o kernel_elf-kern_loader.o kernel_elf-kern_rescue.o kernel_elf-kern_term.o kernel_elf-term_ieee1275_ofconsole.o kernel_elf-kern_sparc64_ieee1275_openfw.o kernel_elf-disk_ieee1275_ofdisk.o kernel_elf-kern_partition.o kernel_elf-kern_env.o kernel_elf-kern_sparc64_dl.o kernel_elf-symlist.o kernel_elf-kern_generic_millisleep.o kernel_elf-kern_generic_get_time_ms.o kernel_elf-kern_sparc64_cache.o kernel_elf-kern_parser.o $(TARGET_LDFLAGS) $(kernel_elf_LDFLAGS) + +kernel_elf-kern_sparc64_ieee1275_init.o: kern/sparc64/ieee1275/init.c $(kern/sparc64/ieee1275/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/sparc64/ieee1275 -I$(srcdir)/kern/sparc64/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_sparc64_ieee1275_init.d + +kernel_elf-kern_ieee1275_ieee1275.o: kern/ieee1275/ieee1275.c $(kern/ieee1275/ieee1275.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/ieee1275 -I$(srcdir)/kern/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_ieee1275_ieee1275.d + +kernel_elf-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_main.d + +kernel_elf-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_device.d + +kernel_elf-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_disk.d + +kernel_elf-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_dl.d + +kernel_elf-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_file.d + +kernel_elf-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_fs.d + +kernel_elf-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_err.d + +kernel_elf-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_misc.d + +kernel_elf-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_mm.d + +kernel_elf-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_loader.d + +kernel_elf-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_rescue.d + +kernel_elf-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_term.d + +kernel_elf-term_ieee1275_ofconsole.o: term/ieee1275/ofconsole.c $(term/ieee1275/ofconsole.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/ieee1275 -I$(srcdir)/term/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-term_ieee1275_ofconsole.d + +kernel_elf-kern_sparc64_ieee1275_openfw.o: kern/sparc64/ieee1275/openfw.c $(kern/sparc64/ieee1275/openfw.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/sparc64/ieee1275 -I$(srcdir)/kern/sparc64/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_sparc64_ieee1275_openfw.d + +kernel_elf-disk_ieee1275_ofdisk.o: disk/ieee1275/ofdisk.c $(disk/ieee1275/ofdisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/ieee1275 -I$(srcdir)/disk/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-disk_ieee1275_ofdisk.d + +kernel_elf-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_partition.d + +kernel_elf-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_env.d + +kernel_elf-kern_sparc64_dl.o: kern/sparc64/dl.c $(kern/sparc64/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/sparc64 -I$(srcdir)/kern/sparc64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_sparc64_dl.d + +kernel_elf-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-symlist.d + +kernel_elf-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_millisleep.d + +kernel_elf-kern_generic_get_time_ms.o: kern/generic/get_time_ms.c $(kern/generic/get_time_ms.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_generic_get_time_ms.d + +kernel_elf-kern_sparc64_cache.o: kern/sparc64/cache.S $(kern/sparc64/cache.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/sparc64 -I$(srcdir)/kern/sparc64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_sparc64_cache.d + +kernel_elf-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_elf_CFLAGS) -MD -c -o $@ $< +-include kernel_elf-kern_parser.d + +kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc + +# Modules. +#_linux.mod linux.mod +pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \ + hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \ + boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \ + pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \ + configfile.mod search.mod gzio.mod xfs.mod \ + affs.mod sfs.mod acorn.mod + +# For fshelp.mod. +fshelp_mod_SOURCES = fs/fshelp.c +CLEANFILES += fshelp.mod mod-fshelp.o mod-fshelp.c pre-fshelp.o fshelp_mod-fs_fshelp.o und-fshelp.lst +ifneq ($(fshelp_mod_EXPORTS),no) +CLEANFILES += def-fshelp.lst +DEFSYMFILES += def-fshelp.lst +endif +MOSTLYCLEANFILES += fshelp_mod-fs_fshelp.d +UNDSYMFILES += und-fshelp.lst + +fshelp.mod: pre-fshelp.o mod-fshelp.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-fshelp.o mod-fshelp.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-fshelp.o: $(fshelp_mod_DEPENDENCIES) fshelp_mod-fs_fshelp.o + -rm -f $@ + $(TARGET_CC) $(fshelp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fshelp_mod-fs_fshelp.o + +mod-fshelp.o: mod-fshelp.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -c -o $@ $< + +mod-fshelp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fshelp' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(fshelp_mod_EXPORTS),no) +def-fshelp.lst: pre-fshelp.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fshelp/' > $@ +endif + +und-fshelp.lst: pre-fshelp.o + echo 'fshelp' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +fshelp_mod-fs_fshelp.o: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -MD -c -o $@ $< +-include fshelp_mod-fs_fshelp.d + +CLEANFILES += cmd-fshelp_mod-fs_fshelp.lst fs-fshelp_mod-fs_fshelp.lst partmap-fshelp_mod-fs_fshelp.lst +COMMANDFILES += cmd-fshelp_mod-fs_fshelp.lst +FSFILES += fs-fshelp_mod-fs_fshelp.lst +PARTMAPFILES += partmap-fshelp_mod-fs_fshelp.lst + +cmd-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh fshelp > $@ || (rm -f $@; exit 1) + +fs-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh fshelp > $@ || (rm -f $@; exit 1) + +partmap-fshelp_mod-fs_fshelp.lst: fs/fshelp.c $(fs/fshelp.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fshelp_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh fshelp > $@ || (rm -f $@; exit 1) + + +fshelp_mod_CFLAGS = $(COMMON_CFLAGS) +fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +CLEANFILES += fat.mod mod-fat.o mod-fat.c pre-fat.o fat_mod-fs_fat.o und-fat.lst +ifneq ($(fat_mod_EXPORTS),no) +CLEANFILES += def-fat.lst +DEFSYMFILES += def-fat.lst +endif +MOSTLYCLEANFILES += fat_mod-fs_fat.d +UNDSYMFILES += und-fat.lst + +fat.mod: pre-fat.o mod-fat.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-fat.o mod-fat.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-fat.o: $(fat_mod_DEPENDENCIES) fat_mod-fs_fat.o + -rm -f $@ + $(TARGET_CC) $(fat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fat_mod-fs_fat.o + +mod-fat.o: mod-fat.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -c -o $@ $< + +mod-fat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'fat' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(fat_mod_EXPORTS),no) +def-fat.lst: pre-fat.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fat/' > $@ +endif + +und-fat.lst: pre-fat.o + echo 'fat' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +fat_mod-fs_fat.o: fs/fat.c $(fs/fat.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -MD -c -o $@ $< +-include fat_mod-fs_fat.d + +CLEANFILES += cmd-fat_mod-fs_fat.lst fs-fat_mod-fs_fat.lst partmap-fat_mod-fs_fat.lst +COMMANDFILES += cmd-fat_mod-fs_fat.lst +FSFILES += fs-fat_mod-fs_fat.lst +PARTMAPFILES += partmap-fat_mod-fs_fat.lst + +cmd-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh fat > $@ || (rm -f $@; exit 1) + +fs-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh fat > $@ || (rm -f $@; exit 1) + +partmap-fat_mod-fs_fat.lst: fs/fat.c $(fs/fat.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fat_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh fat > $@ || (rm -f $@; exit 1) + + +fat_mod_CFLAGS = $(COMMON_CFLAGS) +fat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ext2.mod. +ext2_mod_SOURCES = fs/ext2.c +CLEANFILES += ext2.mod mod-ext2.o mod-ext2.c pre-ext2.o ext2_mod-fs_ext2.o und-ext2.lst +ifneq ($(ext2_mod_EXPORTS),no) +CLEANFILES += def-ext2.lst +DEFSYMFILES += def-ext2.lst +endif +MOSTLYCLEANFILES += ext2_mod-fs_ext2.d +UNDSYMFILES += und-ext2.lst + +ext2.mod: pre-ext2.o mod-ext2.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ext2.o mod-ext2.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ext2.o: $(ext2_mod_DEPENDENCIES) ext2_mod-fs_ext2.o + -rm -f $@ + $(TARGET_CC) $(ext2_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ext2_mod-fs_ext2.o + +mod-ext2.o: mod-ext2.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -c -o $@ $< + +mod-ext2.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ext2' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ext2_mod_EXPORTS),no) +def-ext2.lst: pre-ext2.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ext2/' > $@ +endif + +und-ext2.lst: pre-ext2.o + echo 'ext2' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ext2_mod-fs_ext2.o: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -MD -c -o $@ $< +-include ext2_mod-fs_ext2.d + +CLEANFILES += cmd-ext2_mod-fs_ext2.lst fs-ext2_mod-fs_ext2.lst partmap-ext2_mod-fs_ext2.lst +COMMANDFILES += cmd-ext2_mod-fs_ext2.lst +FSFILES += fs-ext2_mod-fs_ext2.lst +PARTMAPFILES += partmap-ext2_mod-fs_ext2.lst + +cmd-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ext2 > $@ || (rm -f $@; exit 1) + +fs-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ext2 > $@ || (rm -f $@; exit 1) + +partmap-ext2_mod-fs_ext2.lst: fs/ext2.c $(fs/ext2.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ext2_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ext2 > $@ || (rm -f $@; exit 1) + + +ext2_mod_CFLAGS = $(COMMON_CFLAGS) +ext2_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ufs.mod. +ufs_mod_SOURCES = fs/ufs.c +CLEANFILES += ufs.mod mod-ufs.o mod-ufs.c pre-ufs.o ufs_mod-fs_ufs.o und-ufs.lst +ifneq ($(ufs_mod_EXPORTS),no) +CLEANFILES += def-ufs.lst +DEFSYMFILES += def-ufs.lst +endif +MOSTLYCLEANFILES += ufs_mod-fs_ufs.d +UNDSYMFILES += und-ufs.lst + +ufs.mod: pre-ufs.o mod-ufs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ufs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ufs.o mod-ufs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ufs.o: $(ufs_mod_DEPENDENCIES) ufs_mod-fs_ufs.o + -rm -f $@ + $(TARGET_CC) $(ufs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ufs_mod-fs_ufs.o + +mod-ufs.o: mod-ufs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -c -o $@ $< + +mod-ufs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ufs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ufs_mod_EXPORTS),no) +def-ufs.lst: pre-ufs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ufs/' > $@ +endif + +und-ufs.lst: pre-ufs.o + echo 'ufs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ufs_mod-fs_ufs.o: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -MD -c -o $@ $< +-include ufs_mod-fs_ufs.d + +CLEANFILES += cmd-ufs_mod-fs_ufs.lst fs-ufs_mod-fs_ufs.lst partmap-ufs_mod-fs_ufs.lst +COMMANDFILES += cmd-ufs_mod-fs_ufs.lst +FSFILES += fs-ufs_mod-fs_ufs.lst +PARTMAPFILES += partmap-ufs_mod-fs_ufs.lst + +cmd-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ufs > $@ || (rm -f $@; exit 1) + +fs-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ufs > $@ || (rm -f $@; exit 1) + +partmap-ufs_mod-fs_ufs.lst: fs/ufs.c $(fs/ufs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ufs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ufs > $@ || (rm -f $@; exit 1) + + +ufs_mod_CFLAGS = $(COMMON_CFLAGS) +ufs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For minix.mod. +minix_mod_SOURCES = fs/minix.c +CLEANFILES += minix.mod mod-minix.o mod-minix.c pre-minix.o minix_mod-fs_minix.o und-minix.lst +ifneq ($(minix_mod_EXPORTS),no) +CLEANFILES += def-minix.lst +DEFSYMFILES += def-minix.lst +endif +MOSTLYCLEANFILES += minix_mod-fs_minix.d +UNDSYMFILES += und-minix.lst + +minix.mod: pre-minix.o mod-minix.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-minix.o mod-minix.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-minix.o: $(minix_mod_DEPENDENCIES) minix_mod-fs_minix.o + -rm -f $@ + $(TARGET_CC) $(minix_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ minix_mod-fs_minix.o + +mod-minix.o: mod-minix.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -c -o $@ $< + +mod-minix.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'minix' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(minix_mod_EXPORTS),no) +def-minix.lst: pre-minix.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 minix/' > $@ +endif + +und-minix.lst: pre-minix.o + echo 'minix' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +minix_mod-fs_minix.o: fs/minix.c $(fs/minix.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -MD -c -o $@ $< +-include minix_mod-fs_minix.d + +CLEANFILES += cmd-minix_mod-fs_minix.lst fs-minix_mod-fs_minix.lst partmap-minix_mod-fs_minix.lst +COMMANDFILES += cmd-minix_mod-fs_minix.lst +FSFILES += fs-minix_mod-fs_minix.lst +PARTMAPFILES += partmap-minix_mod-fs_minix.lst + +cmd-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh minix > $@ || (rm -f $@; exit 1) + +fs-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh minix > $@ || (rm -f $@; exit 1) + +partmap-minix_mod-fs_minix.lst: fs/minix.c $(fs/minix.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(minix_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh minix > $@ || (rm -f $@; exit 1) + + +minix_mod_CFLAGS = $(COMMON_CFLAGS) +minix_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfs.mod. +hfs_mod_SOURCES = fs/hfs.c +CLEANFILES += hfs.mod mod-hfs.o mod-hfs.c pre-hfs.o hfs_mod-fs_hfs.o und-hfs.lst +ifneq ($(hfs_mod_EXPORTS),no) +CLEANFILES += def-hfs.lst +DEFSYMFILES += def-hfs.lst +endif +MOSTLYCLEANFILES += hfs_mod-fs_hfs.d +UNDSYMFILES += und-hfs.lst + +hfs.mod: pre-hfs.o mod-hfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hfs.o mod-hfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hfs.o: $(hfs_mod_DEPENDENCIES) hfs_mod-fs_hfs.o + -rm -f $@ + $(TARGET_CC) $(hfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hfs_mod-fs_hfs.o + +mod-hfs.o: mod-hfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -c -o $@ $< + +mod-hfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hfs_mod_EXPORTS),no) +def-hfs.lst: pre-hfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hfs/' > $@ +endif + +und-hfs.lst: pre-hfs.o + echo 'hfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hfs_mod-fs_hfs.o: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -MD -c -o $@ $< +-include hfs_mod-fs_hfs.d + +CLEANFILES += cmd-hfs_mod-fs_hfs.lst fs-hfs_mod-fs_hfs.lst partmap-hfs_mod-fs_hfs.lst +COMMANDFILES += cmd-hfs_mod-fs_hfs.lst +FSFILES += fs-hfs_mod-fs_hfs.lst +PARTMAPFILES += partmap-hfs_mod-fs_hfs.lst + +cmd-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hfs > $@ || (rm -f $@; exit 1) + +fs-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hfs > $@ || (rm -f $@; exit 1) + +partmap-hfs_mod-fs_hfs.lst: fs/hfs.c $(fs/hfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hfs > $@ || (rm -f $@; exit 1) + + +hfs_mod_CFLAGS = $(COMMON_CFLAGS) +hfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jfs.mod. +jfs_mod_SOURCES = fs/jfs.c +CLEANFILES += jfs.mod mod-jfs.o mod-jfs.c pre-jfs.o jfs_mod-fs_jfs.o und-jfs.lst +ifneq ($(jfs_mod_EXPORTS),no) +CLEANFILES += def-jfs.lst +DEFSYMFILES += def-jfs.lst +endif +MOSTLYCLEANFILES += jfs_mod-fs_jfs.d +UNDSYMFILES += und-jfs.lst + +jfs.mod: pre-jfs.o mod-jfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-jfs.o mod-jfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-jfs.o: $(jfs_mod_DEPENDENCIES) jfs_mod-fs_jfs.o + -rm -f $@ + $(TARGET_CC) $(jfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ jfs_mod-fs_jfs.o + +mod-jfs.o: mod-jfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -c -o $@ $< + +mod-jfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'jfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(jfs_mod_EXPORTS),no) +def-jfs.lst: pre-jfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jfs/' > $@ +endif + +und-jfs.lst: pre-jfs.o + echo 'jfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +jfs_mod-fs_jfs.o: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -MD -c -o $@ $< +-include jfs_mod-fs_jfs.d + +CLEANFILES += cmd-jfs_mod-fs_jfs.lst fs-jfs_mod-fs_jfs.lst partmap-jfs_mod-fs_jfs.lst +COMMANDFILES += cmd-jfs_mod-fs_jfs.lst +FSFILES += fs-jfs_mod-fs_jfs.lst +PARTMAPFILES += partmap-jfs_mod-fs_jfs.lst + +cmd-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh jfs > $@ || (rm -f $@; exit 1) + +fs-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh jfs > $@ || (rm -f $@; exit 1) + +partmap-jfs_mod-fs_jfs.lst: fs/jfs.c $(fs/jfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(jfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh jfs > $@ || (rm -f $@; exit 1) + + +jfs_mod_CFLAGS = $(COMMON_CFLAGS) +jfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For iso9660.mod. +iso9660_mod_SOURCES = fs/iso9660.c +iso9660_mod_CFLAGS = $(COMMON_CFLAGS) +iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For xfs.mod. +xfs_mod_SOURCES = fs/xfs.c +CLEANFILES += xfs.mod mod-xfs.o mod-xfs.c pre-xfs.o xfs_mod-fs_xfs.o und-xfs.lst +ifneq ($(xfs_mod_EXPORTS),no) +CLEANFILES += def-xfs.lst +DEFSYMFILES += def-xfs.lst +endif +MOSTLYCLEANFILES += xfs_mod-fs_xfs.d +UNDSYMFILES += und-xfs.lst + +xfs.mod: pre-xfs.o mod-xfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-xfs.o mod-xfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-xfs.o: $(xfs_mod_DEPENDENCIES) xfs_mod-fs_xfs.o + -rm -f $@ + $(TARGET_CC) $(xfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ xfs_mod-fs_xfs.o + +mod-xfs.o: mod-xfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -c -o $@ $< + +mod-xfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'xfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(xfs_mod_EXPORTS),no) +def-xfs.lst: pre-xfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 xfs/' > $@ +endif + +und-xfs.lst: pre-xfs.o + echo 'xfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +xfs_mod-fs_xfs.o: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -MD -c -o $@ $< +-include xfs_mod-fs_xfs.d + +CLEANFILES += cmd-xfs_mod-fs_xfs.lst fs-xfs_mod-fs_xfs.lst partmap-xfs_mod-fs_xfs.lst +COMMANDFILES += cmd-xfs_mod-fs_xfs.lst +FSFILES += fs-xfs_mod-fs_xfs.lst +PARTMAPFILES += partmap-xfs_mod-fs_xfs.lst + +cmd-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh xfs > $@ || (rm -f $@; exit 1) + +fs-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh xfs > $@ || (rm -f $@; exit 1) + +partmap-xfs_mod-fs_xfs.lst: fs/xfs.c $(fs/xfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(xfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh xfs > $@ || (rm -f $@; exit 1) + + +xfs_mod_CFLAGS = $(COMMON_CFLAGS) +xfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For affs.mod. +affs_mod_SOURCES = fs/affs.c +CLEANFILES += affs.mod mod-affs.o mod-affs.c pre-affs.o affs_mod-fs_affs.o und-affs.lst +ifneq ($(affs_mod_EXPORTS),no) +CLEANFILES += def-affs.lst +DEFSYMFILES += def-affs.lst +endif +MOSTLYCLEANFILES += affs_mod-fs_affs.d +UNDSYMFILES += und-affs.lst + +affs.mod: pre-affs.o mod-affs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-affs.o mod-affs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-affs.o: $(affs_mod_DEPENDENCIES) affs_mod-fs_affs.o + -rm -f $@ + $(TARGET_CC) $(affs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ affs_mod-fs_affs.o + +mod-affs.o: mod-affs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -c -o $@ $< + +mod-affs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'affs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(affs_mod_EXPORTS),no) +def-affs.lst: pre-affs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 affs/' > $@ +endif + +und-affs.lst: pre-affs.o + echo 'affs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +affs_mod-fs_affs.o: fs/affs.c $(fs/affs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -MD -c -o $@ $< +-include affs_mod-fs_affs.d + +CLEANFILES += cmd-affs_mod-fs_affs.lst fs-affs_mod-fs_affs.lst partmap-affs_mod-fs_affs.lst +COMMANDFILES += cmd-affs_mod-fs_affs.lst +FSFILES += fs-affs_mod-fs_affs.lst +PARTMAPFILES += partmap-affs_mod-fs_affs.lst + +cmd-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh affs > $@ || (rm -f $@; exit 1) + +fs-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh affs > $@ || (rm -f $@; exit 1) + +partmap-affs_mod-fs_affs.lst: fs/affs.c $(fs/affs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(affs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh affs > $@ || (rm -f $@; exit 1) + + +affs_mod_CFLAGS = $(COMMON_CFLAGS) +affs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sfs.mod. +sfs_mod_SOURCES = fs/sfs.c +CLEANFILES += sfs.mod mod-sfs.o mod-sfs.c pre-sfs.o sfs_mod-fs_sfs.o und-sfs.lst +ifneq ($(sfs_mod_EXPORTS),no) +CLEANFILES += def-sfs.lst +DEFSYMFILES += def-sfs.lst +endif +MOSTLYCLEANFILES += sfs_mod-fs_sfs.d +UNDSYMFILES += und-sfs.lst + +sfs.mod: pre-sfs.o mod-sfs.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-sfs.o mod-sfs.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-sfs.o: $(sfs_mod_DEPENDENCIES) sfs_mod-fs_sfs.o + -rm -f $@ + $(TARGET_CC) $(sfs_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sfs_mod-fs_sfs.o + +mod-sfs.o: mod-sfs.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -c -o $@ $< + +mod-sfs.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'sfs' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(sfs_mod_EXPORTS),no) +def-sfs.lst: pre-sfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sfs/' > $@ +endif + +und-sfs.lst: pre-sfs.o + echo 'sfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +sfs_mod-fs_sfs.o: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) + $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -MD -c -o $@ $< +-include sfs_mod-fs_sfs.d + +CLEANFILES += cmd-sfs_mod-fs_sfs.lst fs-sfs_mod-fs_sfs.lst partmap-sfs_mod-fs_sfs.lst +COMMANDFILES += cmd-sfs_mod-fs_sfs.lst +FSFILES += fs-sfs_mod-fs_sfs.lst +PARTMAPFILES += partmap-sfs_mod-fs_sfs.lst + +cmd-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh sfs > $@ || (rm -f $@; exit 1) + +fs-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh sfs > $@ || (rm -f $@; exit 1) + +partmap-sfs_mod-fs_sfs.lst: fs/sfs.c $(fs/sfs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifs -I$(srcdir)/fs $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sfs_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh sfs > $@ || (rm -f $@; exit 1) + + +sfs_mod_CFLAGS = $(COMMON_CFLAGS) +sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +#_linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c +#_linux_mod_CFLAGS = $(COMMON_CFLAGS) +#_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +#linux_mod_SOURCES = loader/sparc64/ieee1275/linux_normal.c +#linux_mod_CFLAGS = $(COMMON_CFLAGS) +#linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/sparc64/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_sparc64_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_sparc64_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_sparc64_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_sparc64_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_sparc64_setjmp.o: normal/sparc64/setjmp.S $(normal/sparc64/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/sparc64 -I$(srcdir)/normal/sparc64 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_sparc64_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_sparc64_setjmp.lst fs-normal_mod-normal_sparc64_setjmp.lst partmap-normal_mod-normal_sparc64_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_sparc64_setjmp.lst +FSFILES += fs-normal_mod-normal_sparc64_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_sparc64_setjmp.lst + +cmd-normal_mod-normal_sparc64_setjmp.lst: normal/sparc64/setjmp.S $(normal/sparc64/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/sparc64 -I$(srcdir)/normal/sparc64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_sparc64_setjmp.lst: normal/sparc64/setjmp.S $(normal/sparc64/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/sparc64 -I$(srcdir)/normal/sparc64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_sparc64_setjmp.lst: normal/sparc64/setjmp.S $(normal/sparc64/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/sparc64 -I$(srcdir)/normal/sparc64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hello.mod. +hello_mod_SOURCES = hello/hello.c +CLEANFILES += hello.mod mod-hello.o mod-hello.c pre-hello.o hello_mod-hello_hello.o und-hello.lst +ifneq ($(hello_mod_EXPORTS),no) +CLEANFILES += def-hello.lst +DEFSYMFILES += def-hello.lst +endif +MOSTLYCLEANFILES += hello_mod-hello_hello.d +UNDSYMFILES += und-hello.lst + +hello.mod: pre-hello.o mod-hello.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-hello.o mod-hello.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-hello.o: $(hello_mod_DEPENDENCIES) hello_mod-hello_hello.o + -rm -f $@ + $(TARGET_CC) $(hello_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ hello_mod-hello_hello.o + +mod-hello.o: mod-hello.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -c -o $@ $< + +mod-hello.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'hello' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(hello_mod_EXPORTS),no) +def-hello.lst: pre-hello.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 hello/' > $@ +endif + +und-hello.lst: pre-hello.o + echo 'hello' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +hello_mod-hello_hello.o: hello/hello.c $(hello/hello.c_DEPENDENCIES) + $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -MD -c -o $@ $< +-include hello_mod-hello_hello.d + +CLEANFILES += cmd-hello_mod-hello_hello.lst fs-hello_mod-hello_hello.lst partmap-hello_mod-hello_hello.lst +COMMANDFILES += cmd-hello_mod-hello_hello.lst +FSFILES += fs-hello_mod-hello_hello.lst +PARTMAPFILES += partmap-hello_mod-hello_hello.lst + +cmd-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh hello > $@ || (rm -f $@; exit 1) + +fs-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh hello > $@ || (rm -f $@; exit 1) + +partmap-hello_mod-hello_hello.lst: hello/hello.c $(hello/hello.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihello -I$(srcdir)/hello $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(hello_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh hello > $@ || (rm -f $@; exit 1) + + +hello_mod_CFLAGS = $(COMMON_CFLAGS) +hello_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For boot.mod. +boot_mod_SOURCES = commands/boot.c +CLEANFILES += boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o und-boot.lst +ifneq ($(boot_mod_EXPORTS),no) +CLEANFILES += def-boot.lst +DEFSYMFILES += def-boot.lst +endif +MOSTLYCLEANFILES += boot_mod-commands_boot.d +UNDSYMFILES += und-boot.lst + +boot.mod: pre-boot.o mod-boot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-boot.o mod-boot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-boot.o: $(boot_mod_DEPENDENCIES) boot_mod-commands_boot.o + -rm -f $@ + $(TARGET_CC) $(boot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ boot_mod-commands_boot.o + +mod-boot.o: mod-boot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -c -o $@ $< + +mod-boot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'boot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(boot_mod_EXPORTS),no) +def-boot.lst: pre-boot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 boot/' > $@ +endif + +und-boot.lst: pre-boot.o + echo 'boot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +boot_mod-commands_boot.o: commands/boot.c $(commands/boot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -MD -c -o $@ $< +-include boot_mod-commands_boot.d + +CLEANFILES += cmd-boot_mod-commands_boot.lst fs-boot_mod-commands_boot.lst partmap-boot_mod-commands_boot.lst +COMMANDFILES += cmd-boot_mod-commands_boot.lst +FSFILES += fs-boot_mod-commands_boot.lst +PARTMAPFILES += partmap-boot_mod-commands_boot.lst + +cmd-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh boot > $@ || (rm -f $@; exit 1) + +fs-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh boot > $@ || (rm -f $@; exit 1) + +partmap-boot_mod-commands_boot.lst: commands/boot.c $(commands/boot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(boot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh boot > $@ || (rm -f $@; exit 1) + + +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminal.mod. +terminal_mod_SOURCES = commands/terminal.c +CLEANFILES += terminal.mod mod-terminal.o mod-terminal.c pre-terminal.o terminal_mod-commands_terminal.o und-terminal.lst +ifneq ($(terminal_mod_EXPORTS),no) +CLEANFILES += def-terminal.lst +DEFSYMFILES += def-terminal.lst +endif +MOSTLYCLEANFILES += terminal_mod-commands_terminal.d +UNDSYMFILES += und-terminal.lst + +terminal.mod: pre-terminal.o mod-terminal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(terminal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-terminal.o mod-terminal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-terminal.o: $(terminal_mod_DEPENDENCIES) terminal_mod-commands_terminal.o + -rm -f $@ + $(TARGET_CC) $(terminal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ terminal_mod-commands_terminal.o + +mod-terminal.o: mod-terminal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -c -o $@ $< + +mod-terminal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'terminal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(terminal_mod_EXPORTS),no) +def-terminal.lst: pre-terminal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 terminal/' > $@ +endif + +und-terminal.lst: pre-terminal.o + echo 'terminal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +terminal_mod-commands_terminal.o: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -MD -c -o $@ $< +-include terminal_mod-commands_terminal.d + +CLEANFILES += cmd-terminal_mod-commands_terminal.lst fs-terminal_mod-commands_terminal.lst partmap-terminal_mod-commands_terminal.lst +COMMANDFILES += cmd-terminal_mod-commands_terminal.lst +FSFILES += fs-terminal_mod-commands_terminal.lst +PARTMAPFILES += partmap-terminal_mod-commands_terminal.lst + +cmd-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh terminal > $@ || (rm -f $@; exit 1) + +fs-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh terminal > $@ || (rm -f $@; exit 1) + +partmap-terminal_mod-commands_terminal.lst: commands/terminal.c $(commands/terminal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(terminal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh terminal > $@ || (rm -f $@; exit 1) + + +terminal_mod_CFLAGS = $(COMMON_CFLAGS) +terminal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ls.mod. +ls_mod_SOURCES = commands/ls.c +CLEANFILES += ls.mod mod-ls.o mod-ls.c pre-ls.o ls_mod-commands_ls.o und-ls.lst +ifneq ($(ls_mod_EXPORTS),no) +CLEANFILES += def-ls.lst +DEFSYMFILES += def-ls.lst +endif +MOSTLYCLEANFILES += ls_mod-commands_ls.d +UNDSYMFILES += und-ls.lst + +ls.mod: pre-ls.o mod-ls.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-ls.o mod-ls.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-ls.o: $(ls_mod_DEPENDENCIES) ls_mod-commands_ls.o + -rm -f $@ + $(TARGET_CC) $(ls_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ ls_mod-commands_ls.o + +mod-ls.o: mod-ls.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -c -o $@ $< + +mod-ls.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'ls' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(ls_mod_EXPORTS),no) +def-ls.lst: pre-ls.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 ls/' > $@ +endif + +und-ls.lst: pre-ls.o + echo 'ls' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +ls_mod-commands_ls.o: commands/ls.c $(commands/ls.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -MD -c -o $@ $< +-include ls_mod-commands_ls.d + +CLEANFILES += cmd-ls_mod-commands_ls.lst fs-ls_mod-commands_ls.lst partmap-ls_mod-commands_ls.lst +COMMANDFILES += cmd-ls_mod-commands_ls.lst +FSFILES += fs-ls_mod-commands_ls.lst +PARTMAPFILES += partmap-ls_mod-commands_ls.lst + +cmd-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh ls > $@ || (rm -f $@; exit 1) + +fs-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh ls > $@ || (rm -f $@; exit 1) + +partmap-ls_mod-commands_ls.lst: commands/ls.c $(commands/ls.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(ls_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh ls > $@ || (rm -f $@; exit 1) + + +ls_mod_CFLAGS = $(COMMON_CFLAGS) +ls_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cmp.mod. +cmp_mod_SOURCES = commands/cmp.c +CLEANFILES += cmp.mod mod-cmp.o mod-cmp.c pre-cmp.o cmp_mod-commands_cmp.o und-cmp.lst +ifneq ($(cmp_mod_EXPORTS),no) +CLEANFILES += def-cmp.lst +DEFSYMFILES += def-cmp.lst +endif +MOSTLYCLEANFILES += cmp_mod-commands_cmp.d +UNDSYMFILES += und-cmp.lst + +cmp.mod: pre-cmp.o mod-cmp.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cmp.o mod-cmp.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cmp.o: $(cmp_mod_DEPENDENCIES) cmp_mod-commands_cmp.o + -rm -f $@ + $(TARGET_CC) $(cmp_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cmp_mod-commands_cmp.o + +mod-cmp.o: mod-cmp.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -c -o $@ $< + +mod-cmp.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cmp' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cmp_mod_EXPORTS),no) +def-cmp.lst: pre-cmp.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cmp/' > $@ +endif + +und-cmp.lst: pre-cmp.o + echo 'cmp' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cmp_mod-commands_cmp.o: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -MD -c -o $@ $< +-include cmp_mod-commands_cmp.d + +CLEANFILES += cmd-cmp_mod-commands_cmp.lst fs-cmp_mod-commands_cmp.lst partmap-cmp_mod-commands_cmp.lst +COMMANDFILES += cmd-cmp_mod-commands_cmp.lst +FSFILES += fs-cmp_mod-commands_cmp.lst +PARTMAPFILES += partmap-cmp_mod-commands_cmp.lst + +cmd-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cmp > $@ || (rm -f $@; exit 1) + +fs-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cmp > $@ || (rm -f $@; exit 1) + +partmap-cmp_mod-commands_cmp.lst: commands/cmp.c $(commands/cmp.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cmp_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cmp > $@ || (rm -f $@; exit 1) + + +cmp_mod_CFLAGS = $(COMMON_CFLAGS) +cmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cat.mod. +cat_mod_SOURCES = commands/cat.c +CLEANFILES += cat.mod mod-cat.o mod-cat.c pre-cat.o cat_mod-commands_cat.o und-cat.lst +ifneq ($(cat_mod_EXPORTS),no) +CLEANFILES += def-cat.lst +DEFSYMFILES += def-cat.lst +endif +MOSTLYCLEANFILES += cat_mod-commands_cat.d +UNDSYMFILES += und-cat.lst + +cat.mod: pre-cat.o mod-cat.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-cat.o mod-cat.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-cat.o: $(cat_mod_DEPENDENCIES) cat_mod-commands_cat.o + -rm -f $@ + $(TARGET_CC) $(cat_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ cat_mod-commands_cat.o + +mod-cat.o: mod-cat.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -c -o $@ $< + +mod-cat.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'cat' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(cat_mod_EXPORTS),no) +def-cat.lst: pre-cat.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 cat/' > $@ +endif + +und-cat.lst: pre-cat.o + echo 'cat' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +cat_mod-commands_cat.o: commands/cat.c $(commands/cat.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -MD -c -o $@ $< +-include cat_mod-commands_cat.d + +CLEANFILES += cmd-cat_mod-commands_cat.lst fs-cat_mod-commands_cat.lst partmap-cat_mod-commands_cat.lst +COMMANDFILES += cmd-cat_mod-commands_cat.lst +FSFILES += fs-cat_mod-commands_cat.lst +PARTMAPFILES += partmap-cat_mod-commands_cat.lst + +cmd-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh cat > $@ || (rm -f $@; exit 1) + +fs-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh cat > $@ || (rm -f $@; exit 1) + +partmap-cat_mod-commands_cat.lst: commands/cat.c $(commands/cat.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(cat_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh cat > $@ || (rm -f $@; exit 1) + + +cat_mod_CFLAGS = $(COMMON_CFLAGS) +cat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For font.mod. +font_mod_SOURCES = font/manager.c +CLEANFILES += font.mod mod-font.o mod-font.c pre-font.o font_mod-font_manager.o und-font.lst +ifneq ($(font_mod_EXPORTS),no) +CLEANFILES += def-font.lst +DEFSYMFILES += def-font.lst +endif +MOSTLYCLEANFILES += font_mod-font_manager.d +UNDSYMFILES += und-font.lst + +font.mod: pre-font.o mod-font.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-font.o mod-font.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-font.o: $(font_mod_DEPENDENCIES) font_mod-font_manager.o + -rm -f $@ + $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ font_mod-font_manager.o + +mod-font.o: mod-font.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -c -o $@ $< + +mod-font.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'font' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(font_mod_EXPORTS),no) +def-font.lst: pre-font.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 font/' > $@ +endif + +und-font.lst: pre-font.o + echo 'font' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +font_mod-font_manager.o: font/manager.c $(font/manager.c_DEPENDENCIES) + $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $< +-include font_mod-font_manager.d + +CLEANFILES += cmd-font_mod-font_manager.lst fs-font_mod-font_manager.lst partmap-font_mod-font_manager.lst +COMMANDFILES += cmd-font_mod-font_manager.lst +FSFILES += fs-font_mod-font_manager.lst +PARTMAPFILES += partmap-font_mod-font_manager.lst + +cmd-font_mod-font_manager.lst: font/manager.c $(font/manager.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1) + +fs-font_mod-font_manager.lst: font/manager.c $(font/manager.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1) + +partmap-font_mod-font_manager.lst: font/manager.c $(font/manager.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1) + + +font_mod_CFLAGS = $(COMMON_CFLAGS) +font_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For amiga.mod +amiga_mod_SOURCES = partmap/amiga.c +CLEANFILES += amiga.mod mod-amiga.o mod-amiga.c pre-amiga.o amiga_mod-partmap_amiga.o und-amiga.lst +ifneq ($(amiga_mod_EXPORTS),no) +CLEANFILES += def-amiga.lst +DEFSYMFILES += def-amiga.lst +endif +MOSTLYCLEANFILES += amiga_mod-partmap_amiga.d +UNDSYMFILES += und-amiga.lst + +amiga.mod: pre-amiga.o mod-amiga.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-amiga.o mod-amiga.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-amiga.o: $(amiga_mod_DEPENDENCIES) amiga_mod-partmap_amiga.o + -rm -f $@ + $(TARGET_CC) $(amiga_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ amiga_mod-partmap_amiga.o + +mod-amiga.o: mod-amiga.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -c -o $@ $< + +mod-amiga.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'amiga' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(amiga_mod_EXPORTS),no) +def-amiga.lst: pre-amiga.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 amiga/' > $@ +endif + +und-amiga.lst: pre-amiga.o + echo 'amiga' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +amiga_mod-partmap_amiga.o: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -MD -c -o $@ $< +-include amiga_mod-partmap_amiga.d + +CLEANFILES += cmd-amiga_mod-partmap_amiga.lst fs-amiga_mod-partmap_amiga.lst partmap-amiga_mod-partmap_amiga.lst +COMMANDFILES += cmd-amiga_mod-partmap_amiga.lst +FSFILES += fs-amiga_mod-partmap_amiga.lst +PARTMAPFILES += partmap-amiga_mod-partmap_amiga.lst + +cmd-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh amiga > $@ || (rm -f $@; exit 1) + +fs-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh amiga > $@ || (rm -f $@; exit 1) + +partmap-amiga_mod-partmap_amiga.lst: partmap/amiga.c $(partmap/amiga.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(amiga_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh amiga > $@ || (rm -f $@; exit 1) + + +amiga_mod_CFLAGS = $(COMMON_CFLAGS) +amiga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For apple.mod +apple_mod_SOURCES = partmap/apple.c +CLEANFILES += apple.mod mod-apple.o mod-apple.c pre-apple.o apple_mod-partmap_apple.o und-apple.lst +ifneq ($(apple_mod_EXPORTS),no) +CLEANFILES += def-apple.lst +DEFSYMFILES += def-apple.lst +endif +MOSTLYCLEANFILES += apple_mod-partmap_apple.d +UNDSYMFILES += und-apple.lst + +apple.mod: pre-apple.o mod-apple.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(apple_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-apple.o mod-apple.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-apple.o: $(apple_mod_DEPENDENCIES) apple_mod-partmap_apple.o + -rm -f $@ + $(TARGET_CC) $(apple_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ apple_mod-partmap_apple.o + +mod-apple.o: mod-apple.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -c -o $@ $< + +mod-apple.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'apple' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(apple_mod_EXPORTS),no) +def-apple.lst: pre-apple.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 apple/' > $@ +endif + +und-apple.lst: pre-apple.o + echo 'apple' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +apple_mod-partmap_apple.o: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -MD -c -o $@ $< +-include apple_mod-partmap_apple.d + +CLEANFILES += cmd-apple_mod-partmap_apple.lst fs-apple_mod-partmap_apple.lst partmap-apple_mod-partmap_apple.lst +COMMANDFILES += cmd-apple_mod-partmap_apple.lst +FSFILES += fs-apple_mod-partmap_apple.lst +PARTMAPFILES += partmap-apple_mod-partmap_apple.lst + +cmd-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh apple > $@ || (rm -f $@; exit 1) + +fs-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh apple > $@ || (rm -f $@; exit 1) + +partmap-apple_mod-partmap_apple.lst: partmap/apple.c $(partmap/apple.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(apple_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh apple > $@ || (rm -f $@; exit 1) + + +apple_mod_CFLAGS = $(COMMON_CFLAGS) +apple_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pc.mod +pc_mod_SOURCES = partmap/pc.c +CLEANFILES += pc.mod mod-pc.o mod-pc.c pre-pc.o pc_mod-partmap_pc.o und-pc.lst +ifneq ($(pc_mod_EXPORTS),no) +CLEANFILES += def-pc.lst +DEFSYMFILES += def-pc.lst +endif +MOSTLYCLEANFILES += pc_mod-partmap_pc.d +UNDSYMFILES += und-pc.lst + +pc.mod: pre-pc.o mod-pc.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pc_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pc.o mod-pc.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pc.o: $(pc_mod_DEPENDENCIES) pc_mod-partmap_pc.o + -rm -f $@ + $(TARGET_CC) $(pc_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pc_mod-partmap_pc.o + +mod-pc.o: mod-pc.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -c -o $@ $< + +mod-pc.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pc' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pc_mod_EXPORTS),no) +def-pc.lst: pre-pc.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pc/' > $@ +endif + +und-pc.lst: pre-pc.o + echo 'pc' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pc_mod-partmap_pc.o: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -MD -c -o $@ $< +-include pc_mod-partmap_pc.d + +CLEANFILES += cmd-pc_mod-partmap_pc.lst fs-pc_mod-partmap_pc.lst partmap-pc_mod-partmap_pc.lst +COMMANDFILES += cmd-pc_mod-partmap_pc.lst +FSFILES += fs-pc_mod-partmap_pc.lst +PARTMAPFILES += partmap-pc_mod-partmap_pc.lst + +cmd-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pc > $@ || (rm -f $@; exit 1) + +fs-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pc > $@ || (rm -f $@; exit 1) + +partmap-pc_mod-partmap_pc.lst: partmap/pc.c $(partmap/pc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pc_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pc > $@ || (rm -f $@; exit 1) + + +pc_mod_CFLAGS = $(COMMON_CFLAGS) +pc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sun.mod +sun_mod_SOURCES = partmap/sun.c +CLEANFILES += sun.mod mod-sun.o mod-sun.c pre-sun.o sun_mod-partmap_sun.o und-sun.lst +ifneq ($(sun_mod_EXPORTS),no) +CLEANFILES += def-sun.lst +DEFSYMFILES += def-sun.lst +endif +MOSTLYCLEANFILES += sun_mod-partmap_sun.d +UNDSYMFILES += und-sun.lst + +sun.mod: pre-sun.o mod-sun.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(sun_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-sun.o mod-sun.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-sun.o: $(sun_mod_DEPENDENCIES) sun_mod-partmap_sun.o + -rm -f $@ + $(TARGET_CC) $(sun_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ sun_mod-partmap_sun.o + +mod-sun.o: mod-sun.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -c -o $@ $< + +mod-sun.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'sun' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(sun_mod_EXPORTS),no) +def-sun.lst: pre-sun.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sun/' > $@ +endif + +und-sun.lst: pre-sun.o + echo 'sun' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +sun_mod-partmap_sun.o: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -MD -c -o $@ $< +-include sun_mod-partmap_sun.d + +CLEANFILES += cmd-sun_mod-partmap_sun.lst fs-sun_mod-partmap_sun.lst partmap-sun_mod-partmap_sun.lst +COMMANDFILES += cmd-sun_mod-partmap_sun.lst +FSFILES += fs-sun_mod-partmap_sun.lst +PARTMAPFILES += partmap-sun_mod-partmap_sun.lst + +cmd-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh sun > $@ || (rm -f $@; exit 1) + +fs-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh sun > $@ || (rm -f $@; exit 1) + +partmap-sun_mod-partmap_sun.lst: partmap/sun.c $(partmap/sun.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(sun_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh sun > $@ || (rm -f $@; exit 1) + + +sun_mod_CFLAGS = $(COMMON_CFLAGS) +sun_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For acorn.mod +acorn_mod_SOURCES = partmap/acorn.c +CLEANFILES += acorn.mod mod-acorn.o mod-acorn.c pre-acorn.o acorn_mod-partmap_acorn.o und-acorn.lst +ifneq ($(acorn_mod_EXPORTS),no) +CLEANFILES += def-acorn.lst +DEFSYMFILES += def-acorn.lst +endif +MOSTLYCLEANFILES += acorn_mod-partmap_acorn.d +UNDSYMFILES += und-acorn.lst + +acorn.mod: pre-acorn.o mod-acorn.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-acorn.o mod-acorn.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-acorn.o: $(acorn_mod_DEPENDENCIES) acorn_mod-partmap_acorn.o + -rm -f $@ + $(TARGET_CC) $(acorn_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ acorn_mod-partmap_acorn.o + +mod-acorn.o: mod-acorn.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -c -o $@ $< + +mod-acorn.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'acorn' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(acorn_mod_EXPORTS),no) +def-acorn.lst: pre-acorn.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 acorn/' > $@ +endif + +und-acorn.lst: pre-acorn.o + echo 'acorn' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +acorn_mod-partmap_acorn.o: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) + $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -MD -c -o $@ $< +-include acorn_mod-partmap_acorn.d + +CLEANFILES += cmd-acorn_mod-partmap_acorn.lst fs-acorn_mod-partmap_acorn.lst partmap-acorn_mod-partmap_acorn.lst +COMMANDFILES += cmd-acorn_mod-partmap_acorn.lst +FSFILES += fs-acorn_mod-partmap_acorn.lst +PARTMAPFILES += partmap-acorn_mod-partmap_acorn.lst + +cmd-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh acorn > $@ || (rm -f $@; exit 1) + +fs-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh acorn > $@ || (rm -f $@; exit 1) + +partmap-acorn_mod-partmap_acorn.lst: partmap/acorn.c $(partmap/acorn.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ipartmap -I$(srcdir)/partmap $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(acorn_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh acorn > $@ || (rm -f $@; exit 1) + + +acorn_mod_CFLAGS = $(COMMON_CFLAGS) + +# For loopback.mod +loopback_mod_SOURCES = disk/loopback.c +CLEANFILES += loopback.mod mod-loopback.o mod-loopback.c pre-loopback.o loopback_mod-disk_loopback.o und-loopback.lst +ifneq ($(loopback_mod_EXPORTS),no) +CLEANFILES += def-loopback.lst +DEFSYMFILES += def-loopback.lst +endif +MOSTLYCLEANFILES += loopback_mod-disk_loopback.d +UNDSYMFILES += und-loopback.lst + +loopback.mod: pre-loopback.o mod-loopback.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-loopback.o mod-loopback.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-loopback.o: $(loopback_mod_DEPENDENCIES) loopback_mod-disk_loopback.o + -rm -f $@ + $(TARGET_CC) $(loopback_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ loopback_mod-disk_loopback.o + +mod-loopback.o: mod-loopback.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -c -o $@ $< + +mod-loopback.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'loopback' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(loopback_mod_EXPORTS),no) +def-loopback.lst: pre-loopback.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 loopback/' > $@ +endif + +und-loopback.lst: pre-loopback.o + echo 'loopback' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +loopback_mod-disk_loopback.o: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) + $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -MD -c -o $@ $< +-include loopback_mod-disk_loopback.d + +CLEANFILES += cmd-loopback_mod-disk_loopback.lst fs-loopback_mod-disk_loopback.lst partmap-loopback_mod-disk_loopback.lst +COMMANDFILES += cmd-loopback_mod-disk_loopback.lst +FSFILES += fs-loopback_mod-disk_loopback.lst +PARTMAPFILES += partmap-loopback_mod-disk_loopback.lst + +cmd-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh loopback > $@ || (rm -f $@; exit 1) + +fs-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh loopback > $@ || (rm -f $@; exit 1) + +partmap-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(loopback_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh loopback > $@ || (rm -f $@; exit 1) + + +loopback_mod_CFLAGS = $(COMMON_CFLAGS) +loopback_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +CLEANFILES += suspend.mod mod-suspend.o mod-suspend.c pre-suspend.o suspend_mod-commands_ieee1275_suspend.o und-suspend.lst +ifneq ($(suspend_mod_EXPORTS),no) +CLEANFILES += def-suspend.lst +DEFSYMFILES += def-suspend.lst +endif +MOSTLYCLEANFILES += suspend_mod-commands_ieee1275_suspend.d +UNDSYMFILES += und-suspend.lst + +suspend.mod: pre-suspend.o mod-suspend.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-suspend.o mod-suspend.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-suspend.o: $(suspend_mod_DEPENDENCIES) suspend_mod-commands_ieee1275_suspend.o + -rm -f $@ + $(TARGET_CC) $(suspend_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ suspend_mod-commands_ieee1275_suspend.o + +mod-suspend.o: mod-suspend.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -c -o $@ $< + +mod-suspend.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'suspend' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(suspend_mod_EXPORTS),no) +def-suspend.lst: pre-suspend.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 suspend/' > $@ +endif + +und-suspend.lst: pre-suspend.o + echo 'suspend' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +suspend_mod-commands_ieee1275_suspend.o: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) + $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -MD -c -o $@ $< +-include suspend_mod-commands_ieee1275_suspend.d + +CLEANFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst fs-suspend_mod-commands_ieee1275_suspend.lst partmap-suspend_mod-commands_ieee1275_suspend.lst +COMMANDFILES += cmd-suspend_mod-commands_ieee1275_suspend.lst +FSFILES += fs-suspend_mod-commands_ieee1275_suspend.lst +PARTMAPFILES += partmap-suspend_mod-commands_ieee1275_suspend.lst + +cmd-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh suspend > $@ || (rm -f $@; exit 1) + +fs-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh suspend > $@ || (rm -f $@; exit 1) + +partmap-suspend_mod-commands_ieee1275_suspend.lst: commands/ieee1275/suspend.c $(commands/ieee1275/suspend.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands/ieee1275 -I$(srcdir)/commands/ieee1275 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(suspend_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh suspend > $@ || (rm -f $@; exit 1) + + +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For help.mod. +help_mod_SOURCES = commands/help.c +CLEANFILES += help.mod mod-help.o mod-help.c pre-help.o help_mod-commands_help.o und-help.lst +ifneq ($(help_mod_EXPORTS),no) +CLEANFILES += def-help.lst +DEFSYMFILES += def-help.lst +endif +MOSTLYCLEANFILES += help_mod-commands_help.d +UNDSYMFILES += und-help.lst + +help.mod: pre-help.o mod-help.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-help.o mod-help.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-help.o: $(help_mod_DEPENDENCIES) help_mod-commands_help.o + -rm -f $@ + $(TARGET_CC) $(help_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ help_mod-commands_help.o + +mod-help.o: mod-help.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -c -o $@ $< + +mod-help.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'help' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(help_mod_EXPORTS),no) +def-help.lst: pre-help.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 help/' > $@ +endif + +und-help.lst: pre-help.o + echo 'help' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +help_mod-commands_help.o: commands/help.c $(commands/help.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -MD -c -o $@ $< +-include help_mod-commands_help.d + +CLEANFILES += cmd-help_mod-commands_help.lst fs-help_mod-commands_help.lst partmap-help_mod-commands_help.lst +COMMANDFILES += cmd-help_mod-commands_help.lst +FSFILES += fs-help_mod-commands_help.lst +PARTMAPFILES += partmap-help_mod-commands_help.lst + +cmd-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh help > $@ || (rm -f $@; exit 1) + +fs-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh help > $@ || (rm -f $@; exit 1) + +partmap-help_mod-commands_help.lst: commands/help.c $(commands/help.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(help_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh help > $@ || (rm -f $@; exit 1) + + +help_mod_CFLAGS = $(COMMON_CFLAGS) +help_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For default.mod +default_mod_SOURCES = commands/default.c +default_mod_CFLAGS = $(COMMON_CFLAGS) +default_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For timeout.mod +timeout_mod_SOURCES = commands/timeout.c +timeout_mod_CFLAGS = $(COMMON_CFLAGS) +timeout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For configfile.mod +configfile_mod_SOURCES = commands/configfile.c +CLEANFILES += configfile.mod mod-configfile.o mod-configfile.c pre-configfile.o configfile_mod-commands_configfile.o und-configfile.lst +ifneq ($(configfile_mod_EXPORTS),no) +CLEANFILES += def-configfile.lst +DEFSYMFILES += def-configfile.lst +endif +MOSTLYCLEANFILES += configfile_mod-commands_configfile.d +UNDSYMFILES += und-configfile.lst + +configfile.mod: pre-configfile.o mod-configfile.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-configfile.o mod-configfile.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-configfile.o: $(configfile_mod_DEPENDENCIES) configfile_mod-commands_configfile.o + -rm -f $@ + $(TARGET_CC) $(configfile_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ configfile_mod-commands_configfile.o + +mod-configfile.o: mod-configfile.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -c -o $@ $< + +mod-configfile.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'configfile' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(configfile_mod_EXPORTS),no) +def-configfile.lst: pre-configfile.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 configfile/' > $@ +endif + +und-configfile.lst: pre-configfile.o + echo 'configfile' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +configfile_mod-commands_configfile.o: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -MD -c -o $@ $< +-include configfile_mod-commands_configfile.d + +CLEANFILES += cmd-configfile_mod-commands_configfile.lst fs-configfile_mod-commands_configfile.lst partmap-configfile_mod-commands_configfile.lst +COMMANDFILES += cmd-configfile_mod-commands_configfile.lst +FSFILES += fs-configfile_mod-commands_configfile.lst +PARTMAPFILES += partmap-configfile_mod-commands_configfile.lst + +cmd-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh configfile > $@ || (rm -f $@; exit 1) + +fs-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh configfile > $@ || (rm -f $@; exit 1) + +partmap-configfile_mod-commands_configfile.lst: commands/configfile.c $(commands/configfile.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(configfile_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh configfile > $@ || (rm -f $@; exit 1) + + +configfile_mod_CFLAGS = $(COMMON_CFLAGS) +configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For search.mod. +search_mod_SOURCES = commands/search.c +CLEANFILES += search.mod mod-search.o mod-search.c pre-search.o search_mod-commands_search.o und-search.lst +ifneq ($(search_mod_EXPORTS),no) +CLEANFILES += def-search.lst +DEFSYMFILES += def-search.lst +endif +MOSTLYCLEANFILES += search_mod-commands_search.d +UNDSYMFILES += und-search.lst + +search.mod: pre-search.o mod-search.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-search.o mod-search.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-search.o: $(search_mod_DEPENDENCIES) search_mod-commands_search.o + -rm -f $@ + $(TARGET_CC) $(search_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ search_mod-commands_search.o + +mod-search.o: mod-search.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -c -o $@ $< + +mod-search.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'search' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(search_mod_EXPORTS),no) +def-search.lst: pre-search.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 search/' > $@ +endif + +und-search.lst: pre-search.o + echo 'search' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +search_mod-commands_search.o: commands/search.c $(commands/search.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -MD -c -o $@ $< +-include search_mod-commands_search.d + +CLEANFILES += cmd-search_mod-commands_search.lst fs-search_mod-commands_search.lst partmap-search_mod-commands_search.lst +COMMANDFILES += cmd-search_mod-commands_search.lst +FSFILES += fs-search_mod-commands_search.lst +PARTMAPFILES += partmap-search_mod-commands_search.lst + +cmd-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh search > $@ || (rm -f $@; exit 1) + +fs-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh search > $@ || (rm -f $@; exit 1) + +partmap-search_mod-commands_search.lst: commands/search.c $(commands/search.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(search_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh search > $@ || (rm -f $@; exit 1) + + +search_mod_CFLAGS = $(COMMON_CFLAGS) +search_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gzio.mod. +gzio_mod_SOURCES = io/gzio.c +CLEANFILES += gzio.mod mod-gzio.o mod-gzio.c pre-gzio.o gzio_mod-io_gzio.o und-gzio.lst +ifneq ($(gzio_mod_EXPORTS),no) +CLEANFILES += def-gzio.lst +DEFSYMFILES += def-gzio.lst +endif +MOSTLYCLEANFILES += gzio_mod-io_gzio.d +UNDSYMFILES += und-gzio.lst + +gzio.mod: pre-gzio.o mod-gzio.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-gzio.o mod-gzio.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-gzio.o: $(gzio_mod_DEPENDENCIES) gzio_mod-io_gzio.o + -rm -f $@ + $(TARGET_CC) $(gzio_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ gzio_mod-io_gzio.o + +mod-gzio.o: mod-gzio.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -c -o $@ $< + +mod-gzio.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'gzio' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(gzio_mod_EXPORTS),no) +def-gzio.lst: pre-gzio.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 gzio/' > $@ +endif + +und-gzio.lst: pre-gzio.o + echo 'gzio' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +gzio_mod-io_gzio.o: io/gzio.c $(io/gzio.c_DEPENDENCIES) + $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -MD -c -o $@ $< +-include gzio_mod-io_gzio.d + +CLEANFILES += cmd-gzio_mod-io_gzio.lst fs-gzio_mod-io_gzio.lst partmap-gzio_mod-io_gzio.lst +COMMANDFILES += cmd-gzio_mod-io_gzio.lst +FSFILES += fs-gzio_mod-io_gzio.lst +PARTMAPFILES += partmap-gzio_mod-io_gzio.lst + +cmd-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh gzio > $@ || (rm -f $@; exit 1) + +fs-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh gzio > $@ || (rm -f $@; exit 1) + +partmap-gzio_mod-io_gzio.lst: io/gzio.c $(io/gzio.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iio -I$(srcdir)/io $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(gzio_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh gzio > $@ || (rm -f $@; exit 1) + + +gzio_mod_CFLAGS = $(COMMON_CFLAGS) +gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For test.mod. +test_mod_SOURCES = commands/test.c +test_mod_CFLAGS = $(COMMON_CFLAGS) +test_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk new file mode 100644 index 0000000..640ceda --- /dev/null +++ b/conf/sparc64-ieee1275.rmk @@ -0,0 +1,292 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc +COMMON_CFLAGS = -ggdb -ffreestanding -m64 -mno-app-regs +COMMON_LDFLAGS = -melf64_sparc -nostdlib + +# Used by various components. These rules need to precede them. +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \ + symbol.h term.h time.h types.h sparc64/libgcc.h loader.h partition.h \ + pc_partition.h ieee1275/ieee1275.h machine/kernel.h + +symlist.c: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# For the parser. +grub_script.tab.c grub_script.tab.h: normal/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_elf_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Programs +pkglib_PROGRAMS = kernel.elf + +# Utilities. +#bin_UTILITIES = grub-mkimage +#ifeq ($(enable_grub_emu), yes) +#bin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \ + util/resolve.c + +# For grub-emu +#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ +# commands/configfile.c commands/default.c commands/help.c \ +# commands/search.c commands/terminal.c commands/ls.c \ +# commands/timeout.c commands/test.c \ +# commands/halt.c commands/reboot.c \ +# disk/loopback.c \ +# fs/affs.c fs/fat.c fs/ext2.c fs/fshelp.c fs/hfs.c fs/iso9660.c \ +# fs/jfs.c fs/minix.c fs/sfs.c fs/ufs.c fs/xfs.c \ +# grub_script.tab.c \ +# io/gzio.c \ +# kern/device.c kern/disk.c kern/dl.c kern/env.c kern/err.c \ +# kern/file.c kern/fs.c kern/loader.c kern/main.c kern/misc.c \ +# kern/parser.c kern/partition.c kern/rescue.c kern/term.c \ +# normal/arg.c normal/cmdline.c normal/command.c \ +# normal/completion.c normal/context.c normal/execute.c \ +# normal/function.c normal/lexer.c \ +# normal/main.c normal/menu.c normal/menu_entry.c \ +# normal/menu_text.c \ +# normal/menu_viewer.c normal/misc.c \ +# partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ +# partmap/acorn.c \ +# util/console.c util/grub-emu.c util/misc.c \ +# util/hostdisk.c util/getroot.c \ +# util/sparc64/ieee1275/misc.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \ + kern/main.c kern/device.c kern/disk.c kern/dl.c kern/file.c \ + kern/fs.c kern/err.c kern/misc.c kern/mm.c kern/loader.c \ + kern/rescue.c kern/term.c term/ieee1275/ofconsole.c \ + kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ + kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \ + kern/generic/millisleep.c kern/generic/get_time_ms.c \ + kern/sparc64/cache.S kern/parser.c +kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h +kernel_elf_CFLAGS = $(COMMON_CFLAGS) +kernel_elf_ASFLAGS = $(COMMON_ASFLAGS) +kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc + +# Modules. +#_linux.mod linux.mod +pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \ + hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \ + boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \ + pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \ + configfile.mod search.mod gzio.mod xfs.mod \ + affs.mod sfs.mod acorn.mod + +# For fshelp.mod. +fshelp_mod_SOURCES = fs/fshelp.c +fshelp_mod_CFLAGS = $(COMMON_CFLAGS) +fshelp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fat.mod. +fat_mod_SOURCES = fs/fat.c +fat_mod_CFLAGS = $(COMMON_CFLAGS) +fat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ext2.mod. +ext2_mod_SOURCES = fs/ext2.c +ext2_mod_CFLAGS = $(COMMON_CFLAGS) +ext2_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ufs.mod. +ufs_mod_SOURCES = fs/ufs.c +ufs_mod_CFLAGS = $(COMMON_CFLAGS) +ufs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For minix.mod. +minix_mod_SOURCES = fs/minix.c +minix_mod_CFLAGS = $(COMMON_CFLAGS) +minix_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hfs.mod. +hfs_mod_SOURCES = fs/hfs.c +hfs_mod_CFLAGS = $(COMMON_CFLAGS) +hfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jfs.mod. +jfs_mod_SOURCES = fs/jfs.c +jfs_mod_CFLAGS = $(COMMON_CFLAGS) +jfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For iso9660.mod. +iso9660_mod_SOURCES = fs/iso9660.c +iso9660_mod_CFLAGS = $(COMMON_CFLAGS) +iso9660_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For xfs.mod. +xfs_mod_SOURCES = fs/xfs.c +xfs_mod_CFLAGS = $(COMMON_CFLAGS) +xfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For affs.mod. +affs_mod_SOURCES = fs/affs.c +affs_mod_CFLAGS = $(COMMON_CFLAGS) +affs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sfs.mod. +sfs_mod_SOURCES = fs/sfs.c +sfs_mod_CFLAGS = $(COMMON_CFLAGS) +sfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +#_linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c +#_linux_mod_CFLAGS = $(COMMON_CFLAGS) +#_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +#linux_mod_SOURCES = loader/sparc64/ieee1275/linux_normal.c +#linux_mod_CFLAGS = $(COMMON_CFLAGS) +#linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/sparc64/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hello.mod. +hello_mod_SOURCES = hello/hello.c +hello_mod_CFLAGS = $(COMMON_CFLAGS) +hello_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For boot.mod. +boot_mod_SOURCES = commands/boot.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For terminal.mod. +terminal_mod_SOURCES = commands/terminal.c +terminal_mod_CFLAGS = $(COMMON_CFLAGS) +terminal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ls.mod. +ls_mod_SOURCES = commands/ls.c +ls_mod_CFLAGS = $(COMMON_CFLAGS) +ls_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cmp.mod. +cmp_mod_SOURCES = commands/cmp.c +cmp_mod_CFLAGS = $(COMMON_CFLAGS) +cmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For cat.mod. +cat_mod_SOURCES = commands/cat.c +cat_mod_CFLAGS = $(COMMON_CFLAGS) +cat_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For font.mod. +font_mod_SOURCES = font/manager.c +font_mod_CFLAGS = $(COMMON_CFLAGS) +font_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For amiga.mod +amiga_mod_SOURCES = partmap/amiga.c +amiga_mod_CFLAGS = $(COMMON_CFLAGS) +amiga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For apple.mod +apple_mod_SOURCES = partmap/apple.c +apple_mod_CFLAGS = $(COMMON_CFLAGS) +apple_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pc.mod +pc_mod_SOURCES = partmap/pc.c +pc_mod_CFLAGS = $(COMMON_CFLAGS) +pc_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For sun.mod +sun_mod_SOURCES = partmap/sun.c +sun_mod_CFLAGS = $(COMMON_CFLAGS) +sun_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For acorn.mod +acorn_mod_SOURCES = partmap/acorn.c +acorn_mod_CFLAGS = $(COMMON_CFLAGS) + +# For loopback.mod +loopback_mod_SOURCES = disk/loopback.c +loopback_mod_CFLAGS = $(COMMON_CFLAGS) +loopback_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For suspend.mod +suspend_mod_SOURCES = commands/ieee1275/suspend.c +suspend_mod_CFLAGS = $(COMMON_CFLAGS) +suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For help.mod. +help_mod_SOURCES = commands/help.c +help_mod_CFLAGS = $(COMMON_CFLAGS) +help_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For default.mod +default_mod_SOURCES = commands/default.c +default_mod_CFLAGS = $(COMMON_CFLAGS) +default_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For timeout.mod +timeout_mod_SOURCES = commands/timeout.c +timeout_mod_CFLAGS = $(COMMON_CFLAGS) +timeout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For configfile.mod +configfile_mod_SOURCES = commands/configfile.c +configfile_mod_CFLAGS = $(COMMON_CFLAGS) +configfile_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For search.mod. +search_mod_SOURCES = commands/search.c +search_mod_CFLAGS = $(COMMON_CFLAGS) +search_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For gzio.mod. +gzio_mod_SOURCES = io/gzio.c +gzio_mod_CFLAGS = $(COMMON_CFLAGS) +gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For test.mod. +test_mod_SOURCES = commands/test.c +test_mod_CFLAGS = $(COMMON_CFLAGS) +test_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/x86_64-efi.mk b/conf/x86_64-efi.mk new file mode 100644 index 0000000..b2095df --- /dev/null +++ b/conf/x86_64-efi.mk @@ -0,0 +1,1824 @@ +# -*- makefile -*- +# Generated by genmk.rb, please don't edit! + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m64 +COMMON_CFLAGS = -fno-builtin -m64 +COMMON_LDFLAGS = -melf_x86_64 -nostdlib + +# Used by various components. These rules need to precede them. +normal/execute.c_DEPENDENCIES = grub_script.tab.h +normal/command.c_DEPENDENCIES = grub_script.tab.h +normal/function.c_DEPENDENCIES = grub_script.tab.h +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Utilities. +bin_UTILITIES = grub-mkimage +#sbin_UTILITIES = grub-mkdevicemap +#ifeq ($(enable_grub_emu), yes) +#sbin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \ + util/resolve.c +CLEANFILES += grub-mkimage$(EXEEXT) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o +MOSTLYCLEANFILES += grub_mkimage-util_i386_efi_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d + +grub-mkimage: $(grub_mkimage_DEPENDENCIES) grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o + $(CC) -o $@ grub_mkimage-util_i386_efi_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o $(LDFLAGS) $(grub_mkimage_LDFLAGS) + +grub_mkimage-util_i386_efi_grub_mkimage.o: util/i386/efi/grub-mkimage.c $(util/i386/efi/grub-mkimage.c_DEPENDENCIES) + $(CC) -Iutil/i386/efi -I$(srcdir)/util/i386/efi $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_i386_efi_grub_mkimage.d + +grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_misc.d + +grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES) + $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< +-include grub_mkimage-util_resolve.d + + +# For grub-setup. +#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ +# util/misc.c util/getroot.c kern/device.c kern/disk.c \ +# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c \ +# fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/hexdump.c lib/hexdump.c \ + commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/context.c normal/main.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/efi/grub-install.in +CLEANFILES += grub-install + +grub-install: util/i386/efi/grub-install.in $(util/i386/efi/grub-install.in_DEPENDENCIES) config.status + ./config.status --file=grub-install:util/i386/efi/grub-install.in + chmod +x $@ + + +# Modules. +pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ + halt.mod reboot.mod _linux.mod linux.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod + +# For kernel.mod. +kernel_mod_EXPORTS = no +kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ + kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ + kern/time.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \ + term/efi/console.c disk/efi/efidisk.c +CLEANFILES += kernel.mod mod-kernel.o mod-kernel.c pre-kernel.o kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_x86_64_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o und-kernel.lst +ifneq ($(kernel_mod_EXPORTS),no) +CLEANFILES += def-kernel.lst +DEFSYMFILES += def-kernel.lst +endif +MOSTLYCLEANFILES += kernel_mod-kern_x86_64_efi_startup.d kernel_mod-kern_x86_64_efi_callwrap.d kernel_mod-kern_main.d kernel_mod-kern_device.d kernel_mod-kern_disk.d kernel_mod-kern_dl.d kernel_mod-kern_file.d kernel_mod-kern_fs.d kernel_mod-kern_err.d kernel_mod-kern_misc.d kernel_mod-kern_mm.d kernel_mod-kern_loader.d kernel_mod-kern_rescue.d kernel_mod-kern_term.d kernel_mod-kern_x86_64_dl.d kernel_mod-kern_i386_efi_init.d kernel_mod-kern_parser.d kernel_mod-kern_partition.d kernel_mod-kern_env.d kernel_mod-symlist.d kernel_mod-kern_efi_efi.d kernel_mod-kern_efi_init.d kernel_mod-kern_efi_mm.d kernel_mod-kern_time.d kernel_mod-kern_i386_tsc.d kernel_mod-kern_i386_pit.d kernel_mod-kern_generic_millisleep.d kernel_mod-kern_generic_rtc_get_time_ms.d kernel_mod-term_efi_console.d kernel_mod-disk_efi_efidisk.d +UNDSYMFILES += und-kernel.lst + +kernel.mod: pre-kernel.o mod-kernel.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-kernel.o mod-kernel.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-kernel.o: $(kernel_mod_DEPENDENCIES) kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_x86_64_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o + -rm -f $@ + $(TARGET_CC) $(kernel_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ kernel_mod-kern_x86_64_efi_startup.o kernel_mod-kern_x86_64_efi_callwrap.o kernel_mod-kern_main.o kernel_mod-kern_device.o kernel_mod-kern_disk.o kernel_mod-kern_dl.o kernel_mod-kern_file.o kernel_mod-kern_fs.o kernel_mod-kern_err.o kernel_mod-kern_misc.o kernel_mod-kern_mm.o kernel_mod-kern_loader.o kernel_mod-kern_rescue.o kernel_mod-kern_term.o kernel_mod-kern_x86_64_dl.o kernel_mod-kern_i386_efi_init.o kernel_mod-kern_parser.o kernel_mod-kern_partition.o kernel_mod-kern_env.o kernel_mod-symlist.o kernel_mod-kern_efi_efi.o kernel_mod-kern_efi_init.o kernel_mod-kern_efi_mm.o kernel_mod-kern_time.o kernel_mod-kern_i386_tsc.o kernel_mod-kern_i386_pit.o kernel_mod-kern_generic_millisleep.o kernel_mod-kern_generic_rtc_get_time_ms.o kernel_mod-term_efi_console.o kernel_mod-disk_efi_efidisk.o + +mod-kernel.o: mod-kernel.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -c -o $@ $< + +mod-kernel.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'kernel' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(kernel_mod_EXPORTS),no) +def-kernel.lst: pre-kernel.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 kernel/' > $@ +endif + +und-kernel.lst: pre-kernel.o + echo 'kernel' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +kernel_mod-kern_x86_64_efi_startup.o: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_x86_64_efi_startup.d + +CLEANFILES += cmd-kernel_mod-kern_x86_64_efi_startup.lst fs-kernel_mod-kern_x86_64_efi_startup.lst partmap-kernel_mod-kern_x86_64_efi_startup.lst +COMMANDFILES += cmd-kernel_mod-kern_x86_64_efi_startup.lst +FSFILES += fs-kernel_mod-kern_x86_64_efi_startup.lst +PARTMAPFILES += partmap-kernel_mod-kern_x86_64_efi_startup.lst + +cmd-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_x86_64_efi_startup.lst: kern/x86_64/efi/startup.S $(kern/x86_64/efi/startup.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_x86_64_efi_callwrap.o: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) + $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_x86_64_efi_callwrap.d + +CLEANFILES += cmd-kernel_mod-kern_x86_64_efi_callwrap.lst fs-kernel_mod-kern_x86_64_efi_callwrap.lst partmap-kernel_mod-kern_x86_64_efi_callwrap.lst +COMMANDFILES += cmd-kernel_mod-kern_x86_64_efi_callwrap.lst +FSFILES += fs-kernel_mod-kern_x86_64_efi_callwrap.lst +PARTMAPFILES += partmap-kernel_mod-kern_x86_64_efi_callwrap.lst + +cmd-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_x86_64_efi_callwrap.lst: kern/x86_64/efi/callwrap.S $(kern/x86_64/efi/callwrap.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/x86_64/efi -I$(srcdir)/kern/x86_64/efi $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(kernel_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_main.o: kern/main.c $(kern/main.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_main.d + +CLEANFILES += cmd-kernel_mod-kern_main.lst fs-kernel_mod-kern_main.lst partmap-kernel_mod-kern_main.lst +COMMANDFILES += cmd-kernel_mod-kern_main.lst +FSFILES += fs-kernel_mod-kern_main.lst +PARTMAPFILES += partmap-kernel_mod-kern_main.lst + +cmd-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_main.lst: kern/main.c $(kern/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_device.o: kern/device.c $(kern/device.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_device.d + +CLEANFILES += cmd-kernel_mod-kern_device.lst fs-kernel_mod-kern_device.lst partmap-kernel_mod-kern_device.lst +COMMANDFILES += cmd-kernel_mod-kern_device.lst +FSFILES += fs-kernel_mod-kern_device.lst +PARTMAPFILES += partmap-kernel_mod-kern_device.lst + +cmd-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_device.lst: kern/device.c $(kern/device.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_disk.o: kern/disk.c $(kern/disk.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_disk.d + +CLEANFILES += cmd-kernel_mod-kern_disk.lst fs-kernel_mod-kern_disk.lst partmap-kernel_mod-kern_disk.lst +COMMANDFILES += cmd-kernel_mod-kern_disk.lst +FSFILES += fs-kernel_mod-kern_disk.lst +PARTMAPFILES += partmap-kernel_mod-kern_disk.lst + +cmd-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_disk.lst: kern/disk.c $(kern/disk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_dl.o: kern/dl.c $(kern/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_dl.d + +CLEANFILES += cmd-kernel_mod-kern_dl.lst fs-kernel_mod-kern_dl.lst partmap-kernel_mod-kern_dl.lst +COMMANDFILES += cmd-kernel_mod-kern_dl.lst +FSFILES += fs-kernel_mod-kern_dl.lst +PARTMAPFILES += partmap-kernel_mod-kern_dl.lst + +cmd-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_dl.lst: kern/dl.c $(kern/dl.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_file.o: kern/file.c $(kern/file.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_file.d + +CLEANFILES += cmd-kernel_mod-kern_file.lst fs-kernel_mod-kern_file.lst partmap-kernel_mod-kern_file.lst +COMMANDFILES += cmd-kernel_mod-kern_file.lst +FSFILES += fs-kernel_mod-kern_file.lst +PARTMAPFILES += partmap-kernel_mod-kern_file.lst + +cmd-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_file.lst: kern/file.c $(kern/file.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_fs.o: kern/fs.c $(kern/fs.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_fs.d + +CLEANFILES += cmd-kernel_mod-kern_fs.lst fs-kernel_mod-kern_fs.lst partmap-kernel_mod-kern_fs.lst +COMMANDFILES += cmd-kernel_mod-kern_fs.lst +FSFILES += fs-kernel_mod-kern_fs.lst +PARTMAPFILES += partmap-kernel_mod-kern_fs.lst + +cmd-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_fs.lst: kern/fs.c $(kern/fs.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_err.o: kern/err.c $(kern/err.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_err.d + +CLEANFILES += cmd-kernel_mod-kern_err.lst fs-kernel_mod-kern_err.lst partmap-kernel_mod-kern_err.lst +COMMANDFILES += cmd-kernel_mod-kern_err.lst +FSFILES += fs-kernel_mod-kern_err.lst +PARTMAPFILES += partmap-kernel_mod-kern_err.lst + +cmd-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_err.lst: kern/err.c $(kern/err.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_misc.o: kern/misc.c $(kern/misc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_misc.d + +CLEANFILES += cmd-kernel_mod-kern_misc.lst fs-kernel_mod-kern_misc.lst partmap-kernel_mod-kern_misc.lst +COMMANDFILES += cmd-kernel_mod-kern_misc.lst +FSFILES += fs-kernel_mod-kern_misc.lst +PARTMAPFILES += partmap-kernel_mod-kern_misc.lst + +cmd-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_misc.lst: kern/misc.c $(kern/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_mm.o: kern/mm.c $(kern/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_mm.d + +CLEANFILES += cmd-kernel_mod-kern_mm.lst fs-kernel_mod-kern_mm.lst partmap-kernel_mod-kern_mm.lst +COMMANDFILES += cmd-kernel_mod-kern_mm.lst +FSFILES += fs-kernel_mod-kern_mm.lst +PARTMAPFILES += partmap-kernel_mod-kern_mm.lst + +cmd-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_mm.lst: kern/mm.c $(kern/mm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_loader.o: kern/loader.c $(kern/loader.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_loader.d + +CLEANFILES += cmd-kernel_mod-kern_loader.lst fs-kernel_mod-kern_loader.lst partmap-kernel_mod-kern_loader.lst +COMMANDFILES += cmd-kernel_mod-kern_loader.lst +FSFILES += fs-kernel_mod-kern_loader.lst +PARTMAPFILES += partmap-kernel_mod-kern_loader.lst + +cmd-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_loader.lst: kern/loader.c $(kern/loader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_rescue.o: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_rescue.d + +CLEANFILES += cmd-kernel_mod-kern_rescue.lst fs-kernel_mod-kern_rescue.lst partmap-kernel_mod-kern_rescue.lst +COMMANDFILES += cmd-kernel_mod-kern_rescue.lst +FSFILES += fs-kernel_mod-kern_rescue.lst +PARTMAPFILES += partmap-kernel_mod-kern_rescue.lst + +cmd-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_rescue.lst: kern/rescue.c $(kern/rescue.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_term.o: kern/term.c $(kern/term.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_term.d + +CLEANFILES += cmd-kernel_mod-kern_term.lst fs-kernel_mod-kern_term.lst partmap-kernel_mod-kern_term.lst +COMMANDFILES += cmd-kernel_mod-kern_term.lst +FSFILES += fs-kernel_mod-kern_term.lst +PARTMAPFILES += partmap-kernel_mod-kern_term.lst + +cmd-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_term.lst: kern/term.c $(kern/term.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_x86_64_dl.o: kern/x86_64/dl.c $(kern/x86_64/dl.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/x86_64 -I$(srcdir)/kern/x86_64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_x86_64_dl.d + +CLEANFILES += cmd-kernel_mod-kern_x86_64_dl.lst fs-kernel_mod-kern_x86_64_dl.lst partmap-kernel_mod-kern_x86_64_dl.lst +COMMANDFILES += cmd-kernel_mod-kern_x86_64_dl.lst +FSFILES += fs-kernel_mod-kern_x86_64_dl.lst +PARTMAPFILES += partmap-kernel_mod-kern_x86_64_dl.lst + +cmd-kernel_mod-kern_x86_64_dl.lst: kern/x86_64/dl.c $(kern/x86_64/dl.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/x86_64 -I$(srcdir)/kern/x86_64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_x86_64_dl.lst: kern/x86_64/dl.c $(kern/x86_64/dl.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/x86_64 -I$(srcdir)/kern/x86_64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_x86_64_dl.lst: kern/x86_64/dl.c $(kern/x86_64/dl.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/x86_64 -I$(srcdir)/kern/x86_64 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_efi_init.o: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_efi_init.d + +CLEANFILES += cmd-kernel_mod-kern_i386_efi_init.lst fs-kernel_mod-kern_i386_efi_init.lst partmap-kernel_mod-kern_i386_efi_init.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_efi_init.lst +FSFILES += fs-kernel_mod-kern_i386_efi_init.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_efi_init.lst + +cmd-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_efi_init.lst: kern/i386/efi/init.c $(kern/i386/efi/init.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386/efi -I$(srcdir)/kern/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_parser.o: kern/parser.c $(kern/parser.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_parser.d + +CLEANFILES += cmd-kernel_mod-kern_parser.lst fs-kernel_mod-kern_parser.lst partmap-kernel_mod-kern_parser.lst +COMMANDFILES += cmd-kernel_mod-kern_parser.lst +FSFILES += fs-kernel_mod-kern_parser.lst +PARTMAPFILES += partmap-kernel_mod-kern_parser.lst + +cmd-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_parser.lst: kern/parser.c $(kern/parser.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_partition.o: kern/partition.c $(kern/partition.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_partition.d + +CLEANFILES += cmd-kernel_mod-kern_partition.lst fs-kernel_mod-kern_partition.lst partmap-kernel_mod-kern_partition.lst +COMMANDFILES += cmd-kernel_mod-kern_partition.lst +FSFILES += fs-kernel_mod-kern_partition.lst +PARTMAPFILES += partmap-kernel_mod-kern_partition.lst + +cmd-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_partition.lst: kern/partition.c $(kern/partition.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_env.o: kern/env.c $(kern/env.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_env.d + +CLEANFILES += cmd-kernel_mod-kern_env.lst fs-kernel_mod-kern_env.lst partmap-kernel_mod-kern_env.lst +COMMANDFILES += cmd-kernel_mod-kern_env.lst +FSFILES += fs-kernel_mod-kern_env.lst +PARTMAPFILES += partmap-kernel_mod-kern_env.lst + +cmd-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_env.lst: kern/env.c $(kern/env.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-symlist.o: symlist.c $(symlist.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-symlist.d + +CLEANFILES += cmd-kernel_mod-symlist.lst fs-kernel_mod-symlist.lst partmap-kernel_mod-symlist.lst +COMMANDFILES += cmd-kernel_mod-symlist.lst +FSFILES += fs-kernel_mod-symlist.lst +PARTMAPFILES += partmap-kernel_mod-symlist.lst + +cmd-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-symlist.lst: symlist.c $(symlist.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_efi.o: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_efi.d + +CLEANFILES += cmd-kernel_mod-kern_efi_efi.lst fs-kernel_mod-kern_efi_efi.lst partmap-kernel_mod-kern_efi_efi.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_efi.lst +FSFILES += fs-kernel_mod-kern_efi_efi.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_efi.lst + +cmd-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_efi.lst: kern/efi/efi.c $(kern/efi/efi.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_init.o: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_init.d + +CLEANFILES += cmd-kernel_mod-kern_efi_init.lst fs-kernel_mod-kern_efi_init.lst partmap-kernel_mod-kern_efi_init.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_init.lst +FSFILES += fs-kernel_mod-kern_efi_init.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_init.lst + +cmd-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_init.lst: kern/efi/init.c $(kern/efi/init.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_efi_mm.o: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_efi_mm.d + +CLEANFILES += cmd-kernel_mod-kern_efi_mm.lst fs-kernel_mod-kern_efi_mm.lst partmap-kernel_mod-kern_efi_mm.lst +COMMANDFILES += cmd-kernel_mod-kern_efi_mm.lst +FSFILES += fs-kernel_mod-kern_efi_mm.lst +PARTMAPFILES += partmap-kernel_mod-kern_efi_mm.lst + +cmd-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_efi_mm.lst: kern/efi/mm.c $(kern/efi/mm.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/efi -I$(srcdir)/kern/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_time.o: kern/time.c $(kern/time.c_DEPENDENCIES) + $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_time.d + +CLEANFILES += cmd-kernel_mod-kern_time.lst fs-kernel_mod-kern_time.lst partmap-kernel_mod-kern_time.lst +COMMANDFILES += cmd-kernel_mod-kern_time.lst +FSFILES += fs-kernel_mod-kern_time.lst +PARTMAPFILES += partmap-kernel_mod-kern_time.lst + +cmd-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_time.lst: kern/time.c $(kern/time.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern -I$(srcdir)/kern $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_tsc.o: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_tsc.d + +CLEANFILES += cmd-kernel_mod-kern_i386_tsc.lst fs-kernel_mod-kern_i386_tsc.lst partmap-kernel_mod-kern_i386_tsc.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_tsc.lst +FSFILES += fs-kernel_mod-kern_i386_tsc.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_tsc.lst + +cmd-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_tsc.lst: kern/i386/tsc.c $(kern/i386/tsc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_i386_pit.o: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_i386_pit.d + +CLEANFILES += cmd-kernel_mod-kern_i386_pit.lst fs-kernel_mod-kern_i386_pit.lst partmap-kernel_mod-kern_i386_pit.lst +COMMANDFILES += cmd-kernel_mod-kern_i386_pit.lst +FSFILES += fs-kernel_mod-kern_i386_pit.lst +PARTMAPFILES += partmap-kernel_mod-kern_i386_pit.lst + +cmd-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_i386_pit.lst: kern/i386/pit.c $(kern/i386/pit.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/i386 -I$(srcdir)/kern/i386 $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_generic_millisleep.o: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_generic_millisleep.d + +CLEANFILES += cmd-kernel_mod-kern_generic_millisleep.lst fs-kernel_mod-kern_generic_millisleep.lst partmap-kernel_mod-kern_generic_millisleep.lst +COMMANDFILES += cmd-kernel_mod-kern_generic_millisleep.lst +FSFILES += fs-kernel_mod-kern_generic_millisleep.lst +PARTMAPFILES += partmap-kernel_mod-kern_generic_millisleep.lst + +cmd-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_generic_millisleep.lst: kern/generic/millisleep.c $(kern/generic/millisleep.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-kern_generic_rtc_get_time_ms.o: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) + $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-kern_generic_rtc_get_time_ms.d + +CLEANFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst fs-kernel_mod-kern_generic_rtc_get_time_ms.lst partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst +COMMANDFILES += cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst +FSFILES += fs-kernel_mod-kern_generic_rtc_get_time_ms.lst +PARTMAPFILES += partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst + +cmd-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-kern_generic_rtc_get_time_ms.lst: kern/generic/rtc_get_time_ms.c $(kern/generic/rtc_get_time_ms.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ikern/generic -I$(srcdir)/kern/generic $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-term_efi_console.o: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) + $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-term_efi_console.d + +CLEANFILES += cmd-kernel_mod-term_efi_console.lst fs-kernel_mod-term_efi_console.lst partmap-kernel_mod-term_efi_console.lst +COMMANDFILES += cmd-kernel_mod-term_efi_console.lst +FSFILES += fs-kernel_mod-term_efi_console.lst +PARTMAPFILES += partmap-kernel_mod-term_efi_console.lst + +cmd-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-term_efi_console.lst: term/efi/console.c $(term/efi/console.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iterm/efi -I$(srcdir)/term/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod-disk_efi_efidisk.o: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) + $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -MD -c -o $@ $< +-include kernel_mod-disk_efi_efidisk.d + +CLEANFILES += cmd-kernel_mod-disk_efi_efidisk.lst fs-kernel_mod-disk_efi_efidisk.lst partmap-kernel_mod-disk_efi_efidisk.lst +COMMANDFILES += cmd-kernel_mod-disk_efi_efidisk.lst +FSFILES += fs-kernel_mod-disk_efi_efidisk.lst +PARTMAPFILES += partmap-kernel_mod-disk_efi_efidisk.lst + +cmd-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh kernel > $@ || (rm -f $@; exit 1) + +fs-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh kernel > $@ || (rm -f $@; exit 1) + +partmap-kernel_mod-disk_efi_efidisk.lst: disk/efi/efidisk.c $(disk/efi/efidisk.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Idisk/efi -I$(srcdir)/disk/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(kernel_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh kernel > $@ || (rm -f $@; exit 1) + + +kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + efi/efi.h efi/time.h efi/disk.h machine/loader.h +kernel_mod_CFLAGS = $(COMMON_CFLAGS) +kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) +kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/x86_64/setjmp.S +CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_x86_64_setjmp.o und-normal.lst +ifneq ($(normal_mod_EXPORTS),no) +CLEANFILES += def-normal.lst +DEFSYMFILES += def-normal.lst +endif +MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d normal_mod-normal_command.d normal_mod-normal_completion.d normal_mod-normal_execute.d normal_mod-normal_function.d normal_mod-normal_lexer.d normal_mod-normal_main.d normal_mod-normal_menu.d normal_mod-normal_menu_text.d normal_mod-normal_color.d normal_mod-normal_menu_viewer.d normal_mod-normal_menu_entry.d normal_mod-normal_misc.d normal_mod-grub_script_tab.d normal_mod-normal_script.d normal_mod-normal_x86_64_setjmp.d +UNDSYMFILES += und-normal.lst + +normal.mod: pre-normal.o mod-normal.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-normal.o mod-normal.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-normal.o: $(normal_mod_DEPENDENCIES) normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_x86_64_setjmp.o + -rm -f $@ + $(TARGET_CC) $(normal_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o normal_mod-normal_completion.o normal_mod-normal_execute.o normal_mod-normal_function.o normal_mod-normal_lexer.o normal_mod-normal_main.o normal_mod-normal_menu.o normal_mod-normal_menu_text.o normal_mod-normal_color.o normal_mod-normal_menu_viewer.o normal_mod-normal_menu_entry.o normal_mod-normal_misc.o normal_mod-grub_script_tab.o normal_mod-normal_script.o normal_mod-normal_x86_64_setjmp.o + +mod-normal.o: mod-normal.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -c -o $@ $< + +mod-normal.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'normal' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(normal_mod_EXPORTS),no) +def-normal.lst: pre-normal.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 normal/' > $@ +endif + +und-normal.lst: pre-normal.o + echo 'normal' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +normal_mod-normal_arg.o: normal/arg.c $(normal/arg.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_arg.d + +CLEANFILES += cmd-normal_mod-normal_arg.lst fs-normal_mod-normal_arg.lst partmap-normal_mod-normal_arg.lst +COMMANDFILES += cmd-normal_mod-normal_arg.lst +FSFILES += fs-normal_mod-normal_arg.lst +PARTMAPFILES += partmap-normal_mod-normal_arg.lst + +cmd-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_arg.lst: normal/arg.c $(normal/arg.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_cmdline.o: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_cmdline.d + +CLEANFILES += cmd-normal_mod-normal_cmdline.lst fs-normal_mod-normal_cmdline.lst partmap-normal_mod-normal_cmdline.lst +COMMANDFILES += cmd-normal_mod-normal_cmdline.lst +FSFILES += fs-normal_mod-normal_cmdline.lst +PARTMAPFILES += partmap-normal_mod-normal_cmdline.lst + +cmd-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_cmdline.lst: normal/cmdline.c $(normal/cmdline.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_command.o: normal/command.c $(normal/command.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_command.d + +CLEANFILES += cmd-normal_mod-normal_command.lst fs-normal_mod-normal_command.lst partmap-normal_mod-normal_command.lst +COMMANDFILES += cmd-normal_mod-normal_command.lst +FSFILES += fs-normal_mod-normal_command.lst +PARTMAPFILES += partmap-normal_mod-normal_command.lst + +cmd-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_command.lst: normal/command.c $(normal/command.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_completion.o: normal/completion.c $(normal/completion.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_completion.d + +CLEANFILES += cmd-normal_mod-normal_completion.lst fs-normal_mod-normal_completion.lst partmap-normal_mod-normal_completion.lst +COMMANDFILES += cmd-normal_mod-normal_completion.lst +FSFILES += fs-normal_mod-normal_completion.lst +PARTMAPFILES += partmap-normal_mod-normal_completion.lst + +cmd-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_completion.lst: normal/completion.c $(normal/completion.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_execute.o: normal/execute.c $(normal/execute.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_execute.d + +CLEANFILES += cmd-normal_mod-normal_execute.lst fs-normal_mod-normal_execute.lst partmap-normal_mod-normal_execute.lst +COMMANDFILES += cmd-normal_mod-normal_execute.lst +FSFILES += fs-normal_mod-normal_execute.lst +PARTMAPFILES += partmap-normal_mod-normal_execute.lst + +cmd-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_execute.lst: normal/execute.c $(normal/execute.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_function.o: normal/function.c $(normal/function.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_function.d + +CLEANFILES += cmd-normal_mod-normal_function.lst fs-normal_mod-normal_function.lst partmap-normal_mod-normal_function.lst +COMMANDFILES += cmd-normal_mod-normal_function.lst +FSFILES += fs-normal_mod-normal_function.lst +PARTMAPFILES += partmap-normal_mod-normal_function.lst + +cmd-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_function.lst: normal/function.c $(normal/function.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_lexer.o: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_lexer.d + +CLEANFILES += cmd-normal_mod-normal_lexer.lst fs-normal_mod-normal_lexer.lst partmap-normal_mod-normal_lexer.lst +COMMANDFILES += cmd-normal_mod-normal_lexer.lst +FSFILES += fs-normal_mod-normal_lexer.lst +PARTMAPFILES += partmap-normal_mod-normal_lexer.lst + +cmd-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_lexer.lst: normal/lexer.c $(normal/lexer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_main.o: normal/main.c $(normal/main.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_main.d + +CLEANFILES += cmd-normal_mod-normal_main.lst fs-normal_mod-normal_main.lst partmap-normal_mod-normal_main.lst +COMMANDFILES += cmd-normal_mod-normal_main.lst +FSFILES += fs-normal_mod-normal_main.lst +PARTMAPFILES += partmap-normal_mod-normal_main.lst + +cmd-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_main.lst: normal/main.c $(normal/main.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu.o: normal/menu.c $(normal/menu.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu.d + +CLEANFILES += cmd-normal_mod-normal_menu.lst fs-normal_mod-normal_menu.lst partmap-normal_mod-normal_menu.lst +COMMANDFILES += cmd-normal_mod-normal_menu.lst +FSFILES += fs-normal_mod-normal_menu.lst +PARTMAPFILES += partmap-normal_mod-normal_menu.lst + +cmd-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu.lst: normal/menu.c $(normal/menu.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_text.o: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_text.d + +CLEANFILES += cmd-normal_mod-normal_menu_text.lst fs-normal_mod-normal_menu_text.lst partmap-normal_mod-normal_menu_text.lst +COMMANDFILES += cmd-normal_mod-normal_menu_text.lst +FSFILES += fs-normal_mod-normal_menu_text.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_text.lst + +cmd-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_text.lst: normal/menu_text.c $(normal/menu_text.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_color.o: normal/color.c $(normal/color.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_color.d + +CLEANFILES += cmd-normal_mod-normal_color.lst fs-normal_mod-normal_color.lst partmap-normal_mod-normal_color.lst +COMMANDFILES += cmd-normal_mod-normal_color.lst +FSFILES += fs-normal_mod-normal_color.lst +PARTMAPFILES += partmap-normal_mod-normal_color.lst + +cmd-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_color.lst: normal/color.c $(normal/color.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_viewer.o: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_viewer.d + +CLEANFILES += cmd-normal_mod-normal_menu_viewer.lst fs-normal_mod-normal_menu_viewer.lst partmap-normal_mod-normal_menu_viewer.lst +COMMANDFILES += cmd-normal_mod-normal_menu_viewer.lst +FSFILES += fs-normal_mod-normal_menu_viewer.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_viewer.lst + +cmd-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_viewer.lst: normal/menu_viewer.c $(normal/menu_viewer.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_menu_entry.o: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_menu_entry.d + +CLEANFILES += cmd-normal_mod-normal_menu_entry.lst fs-normal_mod-normal_menu_entry.lst partmap-normal_mod-normal_menu_entry.lst +COMMANDFILES += cmd-normal_mod-normal_menu_entry.lst +FSFILES += fs-normal_mod-normal_menu_entry.lst +PARTMAPFILES += partmap-normal_mod-normal_menu_entry.lst + +cmd-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_menu_entry.lst: normal/menu_entry.c $(normal/menu_entry.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_misc.o: normal/misc.c $(normal/misc.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_misc.d + +CLEANFILES += cmd-normal_mod-normal_misc.lst fs-normal_mod-normal_misc.lst partmap-normal_mod-normal_misc.lst +COMMANDFILES += cmd-normal_mod-normal_misc.lst +FSFILES += fs-normal_mod-normal_misc.lst +PARTMAPFILES += partmap-normal_mod-normal_misc.lst + +cmd-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_misc.lst: normal/misc.c $(normal/misc.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-grub_script_tab.o: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) + $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-grub_script_tab.d + +CLEANFILES += cmd-normal_mod-grub_script_tab.lst fs-normal_mod-grub_script_tab.lst partmap-normal_mod-grub_script_tab.lst +COMMANDFILES += cmd-normal_mod-grub_script_tab.lst +FSFILES += fs-normal_mod-grub_script_tab.lst +PARTMAPFILES += partmap-normal_mod-grub_script_tab.lst + +cmd-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-grub_script_tab.lst: grub_script.tab.c $(grub_script.tab.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -I. -I$(srcdir)/. $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_script.o: normal/script.c $(normal/script.c_DEPENDENCIES) + $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_script.d + +CLEANFILES += cmd-normal_mod-normal_script.lst fs-normal_mod-normal_script.lst partmap-normal_mod-normal_script.lst +COMMANDFILES += cmd-normal_mod-normal_script.lst +FSFILES += fs-normal_mod-normal_script.lst +PARTMAPFILES += partmap-normal_mod-normal_script.lst + +cmd-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_script.lst: normal/script.c $(normal/script.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal -I$(srcdir)/normal $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(normal_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod-normal_x86_64_setjmp.o: normal/x86_64/setjmp.S $(normal/x86_64/setjmp.S_DEPENDENCIES) + $(TARGET_CC) -Inormal/x86_64 -I$(srcdir)/normal/x86_64 $(TARGET_CPPFLAGS) -DASM_FILE=1 $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -MD -c -o $@ $< +-include normal_mod-normal_x86_64_setjmp.d + +CLEANFILES += cmd-normal_mod-normal_x86_64_setjmp.lst fs-normal_mod-normal_x86_64_setjmp.lst partmap-normal_mod-normal_x86_64_setjmp.lst +COMMANDFILES += cmd-normal_mod-normal_x86_64_setjmp.lst +FSFILES += fs-normal_mod-normal_x86_64_setjmp.lst +PARTMAPFILES += partmap-normal_mod-normal_x86_64_setjmp.lst + +cmd-normal_mod-normal_x86_64_setjmp.lst: normal/x86_64/setjmp.S $(normal/x86_64/setjmp.S_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Inormal/x86_64 -I$(srcdir)/normal/x86_64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh normal > $@ || (rm -f $@; exit 1) + +fs-normal_mod-normal_x86_64_setjmp.lst: normal/x86_64/setjmp.S $(normal/x86_64/setjmp.S_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Inormal/x86_64 -I$(srcdir)/normal/x86_64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1) + +partmap-normal_mod-normal_x86_64_setjmp.lst: normal/x86_64/setjmp.S $(normal/x86_64/setjmp.S_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Inormal/x86_64 -I$(srcdir)/normal/x86_64 $(TARGET_CPPFLAGS) $(TARGET_ASFLAGS) $(normal_mod_ASFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh normal > $@ || (rm -f $@; exit 1) + + +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/efi/chainloader.c +CLEANFILES += _chain.mod mod-_chain.o mod-_chain.c pre-_chain.o _chain_mod-loader_efi_chainloader.o und-_chain.lst +ifneq ($(_chain_mod_EXPORTS),no) +CLEANFILES += def-_chain.lst +DEFSYMFILES += def-_chain.lst +endif +MOSTLYCLEANFILES += _chain_mod-loader_efi_chainloader.d +UNDSYMFILES += und-_chain.lst + +_chain.mod: pre-_chain.o mod-_chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_chain.o mod-_chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_chain.o: $(_chain_mod_DEPENDENCIES) _chain_mod-loader_efi_chainloader.o + -rm -f $@ + $(TARGET_CC) $(_chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _chain_mod-loader_efi_chainloader.o + +mod-_chain.o: mod-_chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -c -o $@ $< + +mod-_chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_chain_mod_EXPORTS),no) +def-_chain.lst: pre-_chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _chain/' > $@ +endif + +und-_chain.lst: pre-_chain.o + echo '_chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_chain_mod-loader_efi_chainloader.o: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -MD -c -o $@ $< +-include _chain_mod-loader_efi_chainloader.d + +CLEANFILES += cmd-_chain_mod-loader_efi_chainloader.lst fs-_chain_mod-loader_efi_chainloader.lst partmap-_chain_mod-loader_efi_chainloader.lst +COMMANDFILES += cmd-_chain_mod-loader_efi_chainloader.lst +FSFILES += fs-_chain_mod-loader_efi_chainloader.lst +PARTMAPFILES += partmap-_chain_mod-loader_efi_chainloader.lst + +cmd-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _chain > $@ || (rm -f $@; exit 1) + +fs-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _chain > $@ || (rm -f $@; exit 1) + +partmap-_chain_mod-loader_efi_chainloader.lst: loader/efi/chainloader.c $(loader/efi/chainloader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _chain > $@ || (rm -f $@; exit 1) + + +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/efi/chainloader_normal.c +CLEANFILES += chain.mod mod-chain.o mod-chain.c pre-chain.o chain_mod-loader_efi_chainloader_normal.o und-chain.lst +ifneq ($(chain_mod_EXPORTS),no) +CLEANFILES += def-chain.lst +DEFSYMFILES += def-chain.lst +endif +MOSTLYCLEANFILES += chain_mod-loader_efi_chainloader_normal.d +UNDSYMFILES += und-chain.lst + +chain.mod: pre-chain.o mod-chain.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-chain.o mod-chain.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-chain.o: $(chain_mod_DEPENDENCIES) chain_mod-loader_efi_chainloader_normal.o + -rm -f $@ + $(TARGET_CC) $(chain_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ chain_mod-loader_efi_chainloader_normal.o + +mod-chain.o: mod-chain.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -c -o $@ $< + +mod-chain.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'chain' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(chain_mod_EXPORTS),no) +def-chain.lst: pre-chain.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 chain/' > $@ +endif + +und-chain.lst: pre-chain.o + echo 'chain' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +chain_mod-loader_efi_chainloader_normal.o: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -MD -c -o $@ $< +-include chain_mod-loader_efi_chainloader_normal.d + +CLEANFILES += cmd-chain_mod-loader_efi_chainloader_normal.lst fs-chain_mod-loader_efi_chainloader_normal.lst partmap-chain_mod-loader_efi_chainloader_normal.lst +COMMANDFILES += cmd-chain_mod-loader_efi_chainloader_normal.lst +FSFILES += fs-chain_mod-loader_efi_chainloader_normal.lst +PARTMAPFILES += partmap-chain_mod-loader_efi_chainloader_normal.lst + +cmd-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh chain > $@ || (rm -f $@; exit 1) + +fs-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh chain > $@ || (rm -f $@; exit 1) + +partmap-chain_mod-loader_efi_chainloader_normal.lst: loader/efi/chainloader_normal.c $(loader/efi/chainloader_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(chain_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh chain > $@ || (rm -f $@; exit 1) + + +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For appleldr.mod. +appleldr_mod_SOURCES = loader/efi/appleloader.c +CLEANFILES += appleldr.mod mod-appleldr.o mod-appleldr.c pre-appleldr.o appleldr_mod-loader_efi_appleloader.o und-appleldr.lst +ifneq ($(appleldr_mod_EXPORTS),no) +CLEANFILES += def-appleldr.lst +DEFSYMFILES += def-appleldr.lst +endif +MOSTLYCLEANFILES += appleldr_mod-loader_efi_appleloader.d +UNDSYMFILES += und-appleldr.lst + +appleldr.mod: pre-appleldr.o mod-appleldr.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-appleldr.o mod-appleldr.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-appleldr.o: $(appleldr_mod_DEPENDENCIES) appleldr_mod-loader_efi_appleloader.o + -rm -f $@ + $(TARGET_CC) $(appleldr_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ appleldr_mod-loader_efi_appleloader.o + +mod-appleldr.o: mod-appleldr.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -c -o $@ $< + +mod-appleldr.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'appleldr' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(appleldr_mod_EXPORTS),no) +def-appleldr.lst: pre-appleldr.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 appleldr/' > $@ +endif + +und-appleldr.lst: pre-appleldr.o + echo 'appleldr' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +appleldr_mod-loader_efi_appleloader.o: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -MD -c -o $@ $< +-include appleldr_mod-loader_efi_appleloader.d + +CLEANFILES += cmd-appleldr_mod-loader_efi_appleloader.lst fs-appleldr_mod-loader_efi_appleloader.lst partmap-appleldr_mod-loader_efi_appleloader.lst +COMMANDFILES += cmd-appleldr_mod-loader_efi_appleloader.lst +FSFILES += fs-appleldr_mod-loader_efi_appleloader.lst +PARTMAPFILES += partmap-appleldr_mod-loader_efi_appleloader.lst + +cmd-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh appleldr > $@ || (rm -f $@; exit 1) + +fs-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh appleldr > $@ || (rm -f $@; exit 1) + +partmap-appleldr_mod-loader_efi_appleloader.lst: loader/efi/appleloader.c $(loader/efi/appleloader.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/efi -I$(srcdir)/loader/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(appleldr_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh appleldr > $@ || (rm -f $@; exit 1) + + +appleldr_mod_CFLAGS = $(COMMON_CFLAGS) +appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/efi/linux.c +CLEANFILES += _linux.mod mod-_linux.o mod-_linux.c pre-_linux.o _linux_mod-loader_i386_efi_linux.o und-_linux.lst +ifneq ($(_linux_mod_EXPORTS),no) +CLEANFILES += def-_linux.lst +DEFSYMFILES += def-_linux.lst +endif +MOSTLYCLEANFILES += _linux_mod-loader_i386_efi_linux.d +UNDSYMFILES += und-_linux.lst + +_linux.mod: pre-_linux.o mod-_linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-_linux.o mod-_linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-_linux.o: $(_linux_mod_DEPENDENCIES) _linux_mod-loader_i386_efi_linux.o + -rm -f $@ + $(TARGET_CC) $(_linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ _linux_mod-loader_i386_efi_linux.o + +mod-_linux.o: mod-_linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -c -o $@ $< + +mod-_linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '_linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(_linux_mod_EXPORTS),no) +def-_linux.lst: pre-_linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 _linux/' > $@ +endif + +und-_linux.lst: pre-_linux.o + echo '_linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +_linux_mod-loader_i386_efi_linux.o: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) + $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -MD -c -o $@ $< +-include _linux_mod-loader_i386_efi_linux.d + +CLEANFILES += cmd-_linux_mod-loader_i386_efi_linux.lst fs-_linux_mod-loader_i386_efi_linux.lst partmap-_linux_mod-loader_i386_efi_linux.lst +COMMANDFILES += cmd-_linux_mod-loader_i386_efi_linux.lst +FSFILES += fs-_linux_mod-loader_i386_efi_linux.lst +PARTMAPFILES += partmap-_linux_mod-loader_i386_efi_linux.lst + +cmd-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh _linux > $@ || (rm -f $@; exit 1) + +fs-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh _linux > $@ || (rm -f $@; exit 1) + +partmap-_linux_mod-loader_i386_efi_linux.lst: loader/i386/efi/linux.c $(loader/i386/efi/linux.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader/i386/efi -I$(srcdir)/loader/i386/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(_linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh _linux > $@ || (rm -f $@; exit 1) + + +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +CLEANFILES += linux.mod mod-linux.o mod-linux.c pre-linux.o linux_mod-loader_linux_normal.o und-linux.lst +ifneq ($(linux_mod_EXPORTS),no) +CLEANFILES += def-linux.lst +DEFSYMFILES += def-linux.lst +endif +MOSTLYCLEANFILES += linux_mod-loader_linux_normal.d +UNDSYMFILES += und-linux.lst + +linux.mod: pre-linux.o mod-linux.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-linux.o mod-linux.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-linux.o: $(linux_mod_DEPENDENCIES) linux_mod-loader_linux_normal.o + -rm -f $@ + $(TARGET_CC) $(linux_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ linux_mod-loader_linux_normal.o + +mod-linux.o: mod-linux.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -c -o $@ $< + +mod-linux.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'linux' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(linux_mod_EXPORTS),no) +def-linux.lst: pre-linux.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 linux/' > $@ +endif + +und-linux.lst: pre-linux.o + echo 'linux' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +linux_mod-loader_linux_normal.o: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) + $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -MD -c -o $@ $< +-include linux_mod-loader_linux_normal.d + +CLEANFILES += cmd-linux_mod-loader_linux_normal.lst fs-linux_mod-loader_linux_normal.lst partmap-linux_mod-loader_linux_normal.lst +COMMANDFILES += cmd-linux_mod-loader_linux_normal.lst +FSFILES += fs-linux_mod-loader_linux_normal.lst +PARTMAPFILES += partmap-linux_mod-loader_linux_normal.lst + +cmd-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh linux > $@ || (rm -f $@; exit 1) + +fs-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh linux > $@ || (rm -f $@; exit 1) + +partmap-linux_mod-loader_linux_normal.lst: loader/linux_normal.c $(loader/linux_normal.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Iloader -I$(srcdir)/loader $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(linux_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh linux > $@ || (rm -f $@; exit 1) + + +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +CLEANFILES += halt.mod mod-halt.o mod-halt.c pre-halt.o halt_mod-commands_halt.o und-halt.lst +ifneq ($(halt_mod_EXPORTS),no) +CLEANFILES += def-halt.lst +DEFSYMFILES += def-halt.lst +endif +MOSTLYCLEANFILES += halt_mod-commands_halt.d +UNDSYMFILES += und-halt.lst + +halt.mod: pre-halt.o mod-halt.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-halt.o mod-halt.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-halt.o: $(halt_mod_DEPENDENCIES) halt_mod-commands_halt.o + -rm -f $@ + $(TARGET_CC) $(halt_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ halt_mod-commands_halt.o + +mod-halt.o: mod-halt.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -c -o $@ $< + +mod-halt.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'halt' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(halt_mod_EXPORTS),no) +def-halt.lst: pre-halt.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 halt/' > $@ +endif + +und-halt.lst: pre-halt.o + echo 'halt' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +halt_mod-commands_halt.o: commands/halt.c $(commands/halt.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -MD -c -o $@ $< +-include halt_mod-commands_halt.d + +CLEANFILES += cmd-halt_mod-commands_halt.lst fs-halt_mod-commands_halt.lst partmap-halt_mod-commands_halt.lst +COMMANDFILES += cmd-halt_mod-commands_halt.lst +FSFILES += fs-halt_mod-commands_halt.lst +PARTMAPFILES += partmap-halt_mod-commands_halt.lst + +cmd-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh halt > $@ || (rm -f $@; exit 1) + +fs-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh halt > $@ || (rm -f $@; exit 1) + +partmap-halt_mod-commands_halt.lst: commands/halt.c $(commands/halt.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(halt_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh halt > $@ || (rm -f $@; exit 1) + + +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +CLEANFILES += reboot.mod mod-reboot.o mod-reboot.c pre-reboot.o reboot_mod-commands_reboot.o und-reboot.lst +ifneq ($(reboot_mod_EXPORTS),no) +CLEANFILES += def-reboot.lst +DEFSYMFILES += def-reboot.lst +endif +MOSTLYCLEANFILES += reboot_mod-commands_reboot.d +UNDSYMFILES += und-reboot.lst + +reboot.mod: pre-reboot.o mod-reboot.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-reboot.o mod-reboot.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-reboot.o: $(reboot_mod_DEPENDENCIES) reboot_mod-commands_reboot.o + -rm -f $@ + $(TARGET_CC) $(reboot_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ reboot_mod-commands_reboot.o + +mod-reboot.o: mod-reboot.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -c -o $@ $< + +mod-reboot.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'reboot' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(reboot_mod_EXPORTS),no) +def-reboot.lst: pre-reboot.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 reboot/' > $@ +endif + +und-reboot.lst: pre-reboot.o + echo 'reboot' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +reboot_mod-commands_reboot.o: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -MD -c -o $@ $< +-include reboot_mod-commands_reboot.d + +CLEANFILES += cmd-reboot_mod-commands_reboot.lst fs-reboot_mod-commands_reboot.lst partmap-reboot_mod-commands_reboot.lst +COMMANDFILES += cmd-reboot_mod-commands_reboot.lst +FSFILES += fs-reboot_mod-commands_reboot.lst +PARTMAPFILES += partmap-reboot_mod-commands_reboot.lst + +cmd-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh reboot > $@ || (rm -f $@; exit 1) + +fs-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh reboot > $@ || (rm -f $@; exit 1) + +partmap-reboot_mod-commands_reboot.lst: commands/reboot.c $(commands/reboot.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(reboot_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh reboot > $@ || (rm -f $@; exit 1) + + +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +CLEANFILES += pci.mod mod-pci.o mod-pci.c pre-pci.o pci_mod-bus_pci.o und-pci.lst +ifneq ($(pci_mod_EXPORTS),no) +CLEANFILES += def-pci.lst +DEFSYMFILES += def-pci.lst +endif +MOSTLYCLEANFILES += pci_mod-bus_pci.d +UNDSYMFILES += und-pci.lst + +pci.mod: pre-pci.o mod-pci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-pci.o mod-pci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-pci.o: $(pci_mod_DEPENDENCIES) pci_mod-bus_pci.o + -rm -f $@ + $(TARGET_CC) $(pci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pci_mod-bus_pci.o + +mod-pci.o: mod-pci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -c -o $@ $< + +mod-pci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'pci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(pci_mod_EXPORTS),no) +def-pci.lst: pre-pci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 pci/' > $@ +endif + +und-pci.lst: pre-pci.o + echo 'pci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +pci_mod-bus_pci.o: bus/pci.c $(bus/pci.c_DEPENDENCIES) + $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -MD -c -o $@ $< +-include pci_mod-bus_pci.d + +CLEANFILES += cmd-pci_mod-bus_pci.lst fs-pci_mod-bus_pci.lst partmap-pci_mod-bus_pci.lst +COMMANDFILES += cmd-pci_mod-bus_pci.lst +FSFILES += fs-pci_mod-bus_pci.lst +PARTMAPFILES += partmap-pci_mod-bus_pci.lst + +cmd-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh pci > $@ || (rm -f $@; exit 1) + +fs-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh pci > $@ || (rm -f $@; exit 1) + +partmap-pci_mod-bus_pci.lst: bus/pci.c $(bus/pci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ibus -I$(srcdir)/bus $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(pci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh pci > $@ || (rm -f $@; exit 1) + + +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +CLEANFILES += lspci.mod mod-lspci.o mod-lspci.c pre-lspci.o lspci_mod-commands_lspci.o und-lspci.lst +ifneq ($(lspci_mod_EXPORTS),no) +CLEANFILES += def-lspci.lst +DEFSYMFILES += def-lspci.lst +endif +MOSTLYCLEANFILES += lspci_mod-commands_lspci.d +UNDSYMFILES += und-lspci.lst + +lspci.mod: pre-lspci.o mod-lspci.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-lspci.o mod-lspci.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-lspci.o: $(lspci_mod_DEPENDENCIES) lspci_mod-commands_lspci.o + -rm -f $@ + $(TARGET_CC) $(lspci_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ lspci_mod-commands_lspci.o + +mod-lspci.o: mod-lspci.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -c -o $@ $< + +mod-lspci.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'lspci' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(lspci_mod_EXPORTS),no) +def-lspci.lst: pre-lspci.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 lspci/' > $@ +endif + +und-lspci.lst: pre-lspci.o + echo 'lspci' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +lspci_mod-commands_lspci.o: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -MD -c -o $@ $< +-include lspci_mod-commands_lspci.d + +CLEANFILES += cmd-lspci_mod-commands_lspci.lst fs-lspci_mod-commands_lspci.lst partmap-lspci_mod-commands_lspci.lst +COMMANDFILES += cmd-lspci_mod-commands_lspci.lst +FSFILES += fs-lspci_mod-commands_lspci.lst +PARTMAPFILES += partmap-lspci_mod-commands_lspci.lst + +cmd-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh lspci > $@ || (rm -f $@; exit 1) + +fs-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh lspci > $@ || (rm -f $@; exit 1) + +partmap-lspci_mod-commands_lspci.lst: commands/lspci.c $(commands/lspci.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(lspci_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh lspci > $@ || (rm -f $@; exit 1) + + +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/efi/datetime.c +CLEANFILES += datetime.mod mod-datetime.o mod-datetime.c pre-datetime.o datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o und-datetime.lst +ifneq ($(datetime_mod_EXPORTS),no) +CLEANFILES += def-datetime.lst +DEFSYMFILES += def-datetime.lst +endif +MOSTLYCLEANFILES += datetime_mod-lib_datetime.d datetime_mod-lib_efi_datetime.d +UNDSYMFILES += und-datetime.lst + +datetime.mod: pre-datetime.o mod-datetime.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datetime.o mod-datetime.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datetime.o: $(datetime_mod_DEPENDENCIES) datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o + -rm -f $@ + $(TARGET_CC) $(datetime_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datetime_mod-lib_datetime.o datetime_mod-lib_efi_datetime.o + +mod-datetime.o: mod-datetime.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -c -o $@ $< + +mod-datetime.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datetime' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datetime_mod_EXPORTS),no) +def-datetime.lst: pre-datetime.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datetime/' > $@ +endif + +und-datetime.lst: pre-datetime.o + echo 'datetime' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datetime_mod-lib_datetime.o: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_datetime.lst fs-datetime_mod-lib_datetime.lst partmap-datetime_mod-lib_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_datetime.lst +FSFILES += fs-datetime_mod-lib_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_datetime.lst + +cmd-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_datetime.lst: lib/datetime.c $(lib/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib -I$(srcdir)/lib $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod-lib_efi_datetime.o: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) + $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -MD -c -o $@ $< +-include datetime_mod-lib_efi_datetime.d + +CLEANFILES += cmd-datetime_mod-lib_efi_datetime.lst fs-datetime_mod-lib_efi_datetime.lst partmap-datetime_mod-lib_efi_datetime.lst +COMMANDFILES += cmd-datetime_mod-lib_efi_datetime.lst +FSFILES += fs-datetime_mod-lib_efi_datetime.lst +PARTMAPFILES += partmap-datetime_mod-lib_efi_datetime.lst + +cmd-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datetime > $@ || (rm -f $@; exit 1) + +fs-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datetime > $@ || (rm -f $@; exit 1) + +partmap-datetime_mod-lib_efi_datetime.lst: lib/efi/datetime.c $(lib/efi/datetime.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ilib/efi -I$(srcdir)/lib/efi $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datetime_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datetime > $@ || (rm -f $@; exit 1) + + +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +CLEANFILES += date.mod mod-date.o mod-date.c pre-date.o date_mod-commands_date.o und-date.lst +ifneq ($(date_mod_EXPORTS),no) +CLEANFILES += def-date.lst +DEFSYMFILES += def-date.lst +endif +MOSTLYCLEANFILES += date_mod-commands_date.d +UNDSYMFILES += und-date.lst + +date.mod: pre-date.o mod-date.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-date.o mod-date.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-date.o: $(date_mod_DEPENDENCIES) date_mod-commands_date.o + -rm -f $@ + $(TARGET_CC) $(date_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ date_mod-commands_date.o + +mod-date.o: mod-date.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -c -o $@ $< + +mod-date.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'date' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(date_mod_EXPORTS),no) +def-date.lst: pre-date.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 date/' > $@ +endif + +und-date.lst: pre-date.o + echo 'date' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +date_mod-commands_date.o: commands/date.c $(commands/date.c_DEPENDENCIES) + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -MD -c -o $@ $< +-include date_mod-commands_date.d + +CLEANFILES += cmd-date_mod-commands_date.lst fs-date_mod-commands_date.lst partmap-date_mod-commands_date.lst +COMMANDFILES += cmd-date_mod-commands_date.lst +FSFILES += fs-date_mod-commands_date.lst +PARTMAPFILES += partmap-date_mod-commands_date.lst + +cmd-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh date > $@ || (rm -f $@; exit 1) + +fs-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh date > $@ || (rm -f $@; exit 1) + +partmap-date_mod-commands_date.lst: commands/date.c $(commands/date.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(date_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh date > $@ || (rm -f $@; exit 1) + + +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +CLEANFILES += datehook.mod mod-datehook.o mod-datehook.c pre-datehook.o datehook_mod-hook_datehook.o und-datehook.lst +ifneq ($(datehook_mod_EXPORTS),no) +CLEANFILES += def-datehook.lst +DEFSYMFILES += def-datehook.lst +endif +MOSTLYCLEANFILES += datehook_mod-hook_datehook.d +UNDSYMFILES += und-datehook.lst + +datehook.mod: pre-datehook.o mod-datehook.o $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ pre-datehook.o mod-datehook.o + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +pre-datehook.o: $(datehook_mod_DEPENDENCIES) datehook_mod-hook_datehook.o + -rm -f $@ + $(TARGET_CC) $(datehook_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ datehook_mod-hook_datehook.o + +mod-datehook.o: mod-datehook.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -c -o $@ $< + +mod-datehook.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'datehook' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(datehook_mod_EXPORTS),no) +def-datehook.lst: pre-datehook.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 datehook/' > $@ +endif + +und-datehook.lst: pre-datehook.o + echo 'datehook' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +datehook_mod-hook_datehook.o: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) + $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -MD -c -o $@ $< +-include datehook_mod-hook_datehook.d + +CLEANFILES += cmd-datehook_mod-hook_datehook.lst fs-datehook_mod-hook_datehook.lst partmap-datehook_mod-hook_datehook.lst +COMMANDFILES += cmd-datehook_mod-hook_datehook.lst +FSFILES += fs-datehook_mod-hook_datehook.lst +PARTMAPFILES += partmap-datehook_mod-hook_datehook.lst + +cmd-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) gencmdlist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh datehook > $@ || (rm -f $@; exit 1) + +fs-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genfslist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh datehook > $@ || (rm -f $@; exit 1) + +partmap-datehook_mod-hook_datehook.lst: hook/datehook.c $(hook/datehook.c_DEPENDENCIES) genpartmaplist.sh + set -e; $(TARGET_CC) -Ihook -I$(srcdir)/hook $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(datehook_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh datehook > $@ || (rm -f $@; exit 1) + + +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk new file mode 100644 index 0000000..5b108d2 --- /dev/null +++ b/conf/x86_64-efi.rmk @@ -0,0 +1,197 @@ +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m64 +COMMON_CFLAGS = -fno-builtin -m64 +COMMON_LDFLAGS = -melf_x86_64 -nostdlib + +# Used by various components. These rules need to precede them. +normal/execute.c_DEPENDENCIES = grub_script.tab.h +normal/command.c_DEPENDENCIES = grub_script.tab.h +normal/function.c_DEPENDENCIES = grub_script.tab.h +normal/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Utilities. +bin_UTILITIES = grub-mkimage +#sbin_UTILITIES = grub-mkdevicemap +#ifeq ($(enable_grub_emu), yes) +#sbin_UTILITIES += grub-emu +#endif + +# For grub-mkimage. +grub_mkimage_SOURCES = util/i386/efi/grub-mkimage.c util/misc.c \ + util/resolve.c + +# For grub-setup. +#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ +# util/misc.c util/getroot.c kern/device.c kern/disk.c \ +# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/pc.c \ +# fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c + +# For grub-emu. +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/terminal.c commands/ls.c commands/test.c \ + commands/search.c commands/hexdump.c lib/hexdump.c \ + commands/halt.c commands/reboot.c \ + commands/i386/cpuid.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/xfs.c fs/afs.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c \ + normal/execute.c kern/file.c kern/fs.c normal/lexer.c \ + kern/loader.c kern/main.c kern/misc.c kern/parser.c \ + grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c \ + normal/arg.c normal/cmdline.c normal/command.c normal/function.c\ + normal/completion.c normal/context.c normal/main.c \ + normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ + normal/menu_text.c \ + normal/misc.c normal/script.c \ + normal/color.c \ + partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c \ + partmap/acorn.c partmap/gpt.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + util/i386/pc/misc.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/efi/grub-install.in + +# Modules. +pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \ + halt.mod reboot.mod _linux.mod linux.mod pci.mod lspci.mod \ + datetime.mod date.mod datehook.mod + +# For kernel.mod. +kernel_mod_EXPORTS = no +kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ + kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ + kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ + kern/time.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \ + term/efi/console.c disk/efi/efidisk.c +kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ + efi/efi.h efi/time.h efi/disk.h machine/loader.h +kernel_mod_CFLAGS = $(COMMON_CFLAGS) +kernel_mod_ASFLAGS = $(COMMON_ASFLAGS) +kernel_mod_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# +# Only arch dependant part of normal.mod will be here. Common part for +# all architecures of normal.mod is at start and should be kept at sync +# with other makefiles. +# +# Please put arch dependant part of normal.mod at the end of list to +# keep it simpler to update to different architectures. +# +normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c \ + normal/completion.c normal/execute.c \ + normal/function.c normal/lexer.c normal/main.c normal/menu.c \ + normal/menu_text.c \ + normal/color.c \ + normal/menu_viewer.c normal/menu_entry.c \ + normal/misc.c grub_script.tab.c \ + normal/script.c \ + normal/x86_64/setjmp.S +normal_mod_CFLAGS = $(COMMON_CFLAGS) +normal_mod_ASFLAGS = $(COMMON_ASFLAGS) +normal_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _chain.mod. +_chain_mod_SOURCES = loader/efi/chainloader.c +_chain_mod_CFLAGS = $(COMMON_CFLAGS) +_chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/efi/chainloader_normal.c +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For appleldr.mod. +appleldr_mod_SOURCES = loader/efi/appleloader.c +appleldr_mod_CFLAGS = $(COMMON_CFLAGS) +appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For _linux.mod. +_linux_mod_SOURCES = loader/i386/efi/linux.c +_linux_mod_CFLAGS = $(COMMON_CFLAGS) +_linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/linux_normal.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/datetime.c lib/efi/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..3f51f4e --- /dev/null +++ b/config.guess @@ -0,0 +1,1552 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-12-19' + +# This file 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd | genuineintel) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..91e9615 --- /dev/null +++ b/config.h.in @@ -0,0 +1,131 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define it if GAS requires that absolute indirect calls/jumps are not + prefixed with an asterisk */ +#undef ABSOLUTE_WITHOUT_ASTERISK + +/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */ +#undef ADDR32 + +/* Define it to one of __bss_start, edata and _edata */ +#undef BSS_START_SYMBOL + +/* Define it to \"data32\" or \"data32;\" to make GAS happy */ +#undef DATA32 + +/* Use lzma compression */ +#undef ENABLE_LZMA + +/* Use lzo compression */ +#undef ENABLE_LZO + +/* Define it to either end or _end */ +#undef END_SYMBOL + +/* Define if C symbols get an underscore after compilation */ +#undef HAVE_ASM_USCORE + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_CURSES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LZO1X_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LZO_LZO1X_H + +/* Define to 1 if you have the `memalign' function. */ +#undef HAVE_MEMALIGN + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NCURSES_CURSES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NCURSES_H + +/* Define to 1 if you have the `posix_memalign' function. */ +#undef HAVE_POSIX_MEMALIGN + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_USB_H + +/* Define to 1 if you enable memory manager debugging. */ +#undef MM_DEBUG + +/* Define to 1 if GCC generates calls to __enable_execute_stack() */ +#undef NEED_ENABLE_EXECUTE_STACK + +/* Catch gcc bug */ +#undef NESTED_FUNC_ATTR + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define it to either start or _start */ +#undef START_SYMBOL + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..d8573e8 --- /dev/null +++ b/config.sub @@ -0,0 +1,1681 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2009-01-19' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..c82ee24 --- /dev/null +++ b/configure @@ -0,0 +1,9915 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for GRUB 1.96. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='GRUB' +PACKAGE_TARNAME='grub' +PACKAGE_VERSION='1.96' +PACKAGE_STRING='GRUB 1.96' +PACKAGE_BUGREPORT='bug-grub@gnu.org' + +ac_unique_file="include/grub/dl.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +platform +CMP +YACC +UNIFONT_BDF +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +AWK +SET_MAKE +RUBY +HELP2MAN +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CPP +GREP +EGREP +LIBLZO +enable_lzo +TARGET_IMG_LDSCRIPT +TARGET_IMG_LDFLAGS +TARGET_OBJ2ELF +TARGET_CC +ac_ct_TARGET_CC +OBJCOPY +STRIP +NM +TARGET_CFLAGS +TARGET_CPPFLAGS +TARGET_LDFLAGS +MODULE_LDFLAGS +LIBCURSES +LIBUSB +enable_grub_emu +enable_grub_emu_usb +enable_grub_fstest +enable_grub_pe2elf +FREETYPE +enable_grub_mkfont +freetype_cflags +freetype_libs +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GRUB 1.96 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/grub] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GRUB 1.96:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --enable-lzo use lzo to compress kernel (default is lzma) + --enable-mm-debug include memory manager debugging + --enable-grub-emu build and install the `grub-emu' debugging utility + --enable-grub-emu-usb build and install the `grub-emu' debugging utility + with USB support + --enable-grub-fstest build and install the `grub-fstest' debugging + utility + --enable-grub-pe2elf build and install the `grub-pe2elf' conversion + utility + --enable-grub-mkfont build and install the `grub-mkfont' utility + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-platform=PLATFORM + select the host platform [guessed] + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GRUB configure 1.96 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GRUB $as_me 1.96, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers config.h" + + +# Checks for host and target systems. +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +# Program name transformations +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + + +case "$host_cpu" in + powerpc64) host_m32=1 ;; +esac + +case "$target_cpu" in + i[3456]86) target_cpu=i386 ;; +esac + +# Specify the platform (such as firmware). + +# Check whether --with-platform was given. +if test "${with_platform+set}" = set; then + withval=$with_platform; +fi + + +# Guess the platform if not specified. +if test "x$with_platform" = x; then + case "$target_cpu"-"$target_vendor" in + i386-apple) platform=efi ;; + i386-*) platform=pc ;; + x86_64-apple) platform=efi ;; + x86_64-*) platform=pc ;; + powerpc-*) platform=ieee1275 ;; + powerpc64-*) platform=ieee1275 ;; + sparc64-*) platform=ieee1275 ;; + *) { { echo "$as_me:$LINENO: error: unsupported CPU: \"$target_cpu\"" >&5 +echo "$as_me: error: unsupported CPU: \"$target_cpu\"" >&2;} + { (exit 1); exit 1; }; } ;; + esac +else + platform="$with_platform" +fi + +# Adjust CPU unless target was explicitly specified. +if test -z "$target_alias"; then + case "$target_cpu"-"$platform" in + x86_64-efi) ;; + x86_64-*) target_cpu=i386 ;; + powerpc64-ieee1275) target_cpu=powerpc ;; + esac +fi + +# Check if the platform is supported, make final adjustments. +case "$target_cpu"-"$platform" in + i386-efi) ;; + x86_64-efi) ;; + i386-pc) ;; + i386-coreboot) ;; + i386-linuxbios) platform=coreboot ;; + i386-ieee1275) ;; + powerpc-ieee1275) ;; + sparc64-ieee1275) ;; + *) { { echo "$as_me:$LINENO: error: platform \"$platform\" is not supported for target CPU \"$target_cpu\"" >&5 +echo "$as_me: error: platform \"$platform\" is not supported for target CPU \"$target_cpu\"" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +case "$target_cpu" in + i386 | powerpc) target_m32=1 ;; + x86_64 | sparc64) target_m64=1 ;; +esac + +case "$host_os" in + mingw32) host_os=cygwin ;; +esac + + + + + + + +# +# Checks for build programs. +# + +# Although cmp is listed in the GNU Coding Standards as a command which +# can used directly, OpenBSD lacks cmp in the default installation. +for ac_prog in cmp +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CMP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CMP"; then + ac_cv_prog_CMP="$CMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CMP="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CMP=$ac_cv_prog_CMP +if test -n "$CMP"; then + { echo "$as_me:$LINENO: result: $CMP" >&5 +echo "${ECHO_T}$CMP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CMP" && break +done + +if test "x$CMP" = x; then + { { echo "$as_me:$LINENO: error: cmp is not found" >&5 +echo "$as_me: error: cmp is not found" >&2;} + { (exit 1); exit 1; }; } +fi + +for ac_prog in bison +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_YACC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_YACC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +YACC=$ac_cv_prog_YACC +if test -n "$YACC"; then + { echo "$as_me:$LINENO: result: $YACC" >&5 +echo "${ECHO_T}$YACC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$YACC" && break +done + +if test "x$YACC" = x; then + { { echo "$as_me:$LINENO: error: bison is not found" >&5 +echo "$as_me: error: bison is not found" >&2;} + { (exit 1); exit 1; }; } +fi + +for file in /usr/src/unifont.bdf ; do + if test -e $file ; then + UNIFONT_BDF=$file + + break + fi +done + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# These are not a "must". +# Extract the first word of "ruby", so it can be a program name with args. +set dummy ruby; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RUBY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RUBY in + [\\/]* | ?:[\\/]*) + ac_cv_path_RUBY="$RUBY" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RUBY="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +RUBY=$ac_cv_path_RUBY +if test -n "$RUBY"; then + { echo "$as_me:$LINENO: result: $RUBY" >&5 +echo "${ECHO_T}$RUBY" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "help2man", so it can be a program name with args. +set dummy help2man; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_HELP2MAN+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $HELP2MAN in + [\\/]* | ?:[\\/]*) + ac_cv_path_HELP2MAN="$HELP2MAN" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_HELP2MAN="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +HELP2MAN=$ac_cv_path_HELP2MAN +if test -n "$HELP2MAN"; then + { echo "$as_me:$LINENO: result: $HELP2MAN" >&5 +echo "${ECHO_T}$HELP2MAN" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# +# Checks for host programs. +# + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Must be GCC. +test "x$GCC" = xyes || { { echo "$as_me:$LINENO: error: GCC is required" >&5 +echo "$as_me: error: GCC is required" >&2;} + { (exit 1); exit 1; }; } + + +cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF + + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_largefile_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_largefile_CC=' -n32'; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_file_offset_bits+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_file_offset_bits=no; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_file_offset_bits=64; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -f conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } +if test "${ac_cv_sys_large_files+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_large_files=no; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_sys_large_files=1; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -f conftest* + fi +fi + + +# Identify characteristics of the host architecture. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ + && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) + bogus endian macros +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + # It does; now see whether it defined to BIG_ENDIAN or not. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_bigendian=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_bigendian=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then + ac_cv_c_bigendian=yes +fi +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi +fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +{ echo "$as_me:$LINENO: checking for void *" >&5 +echo $ECHO_N "checking for void *... $ECHO_C" >&6; } +if test "${ac_cv_type_void_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef void * ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_void_p=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_void_p=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_void_p" >&5 +echo "${ECHO_T}$ac_cv_type_void_p" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of void *" >&5 +echo $ECHO_N "checking size of void *... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_void_p+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_void_p=$ac_lo;; +'') if test "$ac_cv_type_void_p" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void *) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_void_p=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef void * ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_void_p=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_void_p" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void *) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_void_p=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5 +echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + +{ echo "$as_me:$LINENO: checking for long" >&5 +echo $ECHO_N "checking for long... $ECHO_C" >&6; } +if test "${ac_cv_type_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef long ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 +echo "${ECHO_T}$ac_cv_type_long" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of long" >&5 +echo $ECHO_N "checking size of long... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long=$ac_lo;; +'') if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef long ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + +if test "x$host_m32" = x1; then + # Force 32-bit mode. + CFLAGS="$CFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" +fi + +# Check LZO when compiling for the i386-pc. +if test "$target_cpu"-"$platform" = i386-pc; then + # Check whether --enable-lzo was given. +if test "${enable_lzo+set}" = set; then + enableval=$enable_lzo; +fi + + if [ x"$enable_lzo" = xyes ]; then + # There are three possibilities. LZO version 2 installed with the name + # liblzo2, with the name liblzo, and LZO version 1. + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_LZO 1 +_ACEOF + + { echo "$as_me:$LINENO: checking for __lzo_init_v2 in -llzo2" >&5 +echo $ECHO_N "checking for __lzo_init_v2 in -llzo2... $ECHO_C" >&6; } +if test "${ac_cv_lib_lzo2___lzo_init_v2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzo2 $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __lzo_init_v2 (); +int +main () +{ +return __lzo_init_v2 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_lzo2___lzo_init_v2=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_lzo2___lzo_init_v2=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_lzo2___lzo_init_v2" >&5 +echo "${ECHO_T}$ac_cv_lib_lzo2___lzo_init_v2" >&6; } +if test $ac_cv_lib_lzo2___lzo_init_v2 = yes; then + LIBLZO="-llzo2" +else + { echo "$as_me:$LINENO: checking for __lzo_init_v2 in -llzo" >&5 +echo $ECHO_N "checking for __lzo_init_v2 in -llzo... $ECHO_C" >&6; } +if test "${ac_cv_lib_lzo___lzo_init_v2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzo $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __lzo_init_v2 (); +int +main () +{ +return __lzo_init_v2 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_lzo___lzo_init_v2=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_lzo___lzo_init_v2=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_lzo___lzo_init_v2" >&5 +echo "${ECHO_T}$ac_cv_lib_lzo___lzo_init_v2" >&6; } +if test $ac_cv_lib_lzo___lzo_init_v2 = yes; then + LIBLZO="-llzo" +else + { echo "$as_me:$LINENO: checking for __lzo_init2 in -llzo" >&5 +echo $ECHO_N "checking for __lzo_init2 in -llzo... $ECHO_C" >&6; } +if test "${ac_cv_lib_lzo___lzo_init2+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzo $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __lzo_init2 (); +int +main () +{ +return __lzo_init2 (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_lzo___lzo_init2=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_lzo___lzo_init2=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_lzo___lzo_init2" >&5 +echo "${ECHO_T}$ac_cv_lib_lzo___lzo_init2" >&6; } +if test $ac_cv_lib_lzo___lzo_init2 = yes; then + LIBLZO="-llzo" +else + { { echo "$as_me:$LINENO: error: LZO library version 1.02 or later is required" >&5 +echo "$as_me: error: LZO library version 1.02 or later is required" >&2;} + { (exit 1); exit 1; }; } +fi + +fi + +fi + + + LIBS="$LIBS $LIBLZO" + { echo "$as_me:$LINENO: checking for lzo1x_999_compress" >&5 +echo $ECHO_N "checking for lzo1x_999_compress... $ECHO_C" >&6; } +if test "${ac_cv_func_lzo1x_999_compress+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define lzo1x_999_compress to an innocuous variant, in case declares lzo1x_999_compress. + For example, HP-UX 11i declares gettimeofday. */ +#define lzo1x_999_compress innocuous_lzo1x_999_compress + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char lzo1x_999_compress (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef lzo1x_999_compress + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char lzo1x_999_compress (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_lzo1x_999_compress || defined __stub___lzo1x_999_compress +choke me +#endif + +int +main () +{ +return lzo1x_999_compress (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_func_lzo1x_999_compress=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_lzo1x_999_compress=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_lzo1x_999_compress" >&5 +echo "${ECHO_T}$ac_cv_func_lzo1x_999_compress" >&6; } +if test $ac_cv_func_lzo1x_999_compress = yes; then + : +else + { { echo "$as_me:$LINENO: error: LZO1X-999 must be enabled" >&5 +echo "$as_me: error: LZO1X-999 must be enabled" >&2;} + { (exit 1); exit 1; }; } +fi + + + # LZO version 2 uses lzo/lzo1x.h, while LZO version 1 uses lzo1x.h. + + +for ac_header in lzo/lzo1x.h lzo1x.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------- ## +## Report this to bug-grub@gnu.org ## +## ------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + else + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_LZMA 1 +_ACEOF + + fi + +fi + +# Check for functions. + + + +for ac_func in posix_memalign memalign asprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# +# Check for target programs. +# + + +# Use linker script if present, otherwise use builtin -N script. +{ echo "$as_me:$LINENO: checking for option to link raw image" >&5 +echo $ECHO_N "checking for option to link raw image... $ECHO_C" >&6; } +if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" +else + TARGET_IMG_LDSCRIPT= + TARGET_IMG_LDFLAGS='-Wl,-N' + TARGET_IMG_LDFLAGS_AC='-Wl,-N' +fi + + +{ echo "$as_me:$LINENO: result: $TARGET_IMG_LDFLAGS_AC" >&5 +echo "${ECHO_T}$TARGET_IMG_LDFLAGS_AC" >&6; } + +# For platforms where ELF is not the default link format. +{ echo "$as_me:$LINENO: checking for command to convert module to ELF format" >&5 +echo $ECHO_N "checking for command to convert module to ELF format... $ECHO_C" >&6; } +case "${host_os}" in + cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;; + *) ;; +esac + +{ echo "$as_me:$LINENO: result: $TARGET_OBJ2ELF" >&5 +echo "${ECHO_T}$TARGET_OBJ2ELF" >&6; } + +# For cross-compiling. +if test "x$build" != "x$host"; then + # XXX this depends on the implementation of autoconf! + tmp_ac_tool_prefix="$ac_tool_prefix" + ac_tool_prefix=$target_alias- + + if test -n "$ac_tool_prefix"; then + for ac_prog in gcc egcs cc + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_TARGET_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$TARGET_CC"; then + ac_cv_prog_TARGET_CC="$TARGET_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_TARGET_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +TARGET_CC=$ac_cv_prog_TARGET_CC +if test -n "$TARGET_CC"; then + { echo "$as_me:$LINENO: result: $TARGET_CC" >&5 +echo "${ECHO_T}$TARGET_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$TARGET_CC" && break + done +fi +if test -z "$TARGET_CC"; then + ac_ct_TARGET_CC=$TARGET_CC + for ac_prog in gcc egcs cc +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_TARGET_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_TARGET_CC"; then + ac_cv_prog_ac_ct_TARGET_CC="$ac_ct_TARGET_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_TARGET_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_TARGET_CC=$ac_cv_prog_ac_ct_TARGET_CC +if test -n "$ac_ct_TARGET_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_TARGET_CC" >&5 +echo "${ECHO_T}$ac_ct_TARGET_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_TARGET_CC" && break +done + + if test "x$ac_ct_TARGET_CC" = x; then + TARGET_CC="{ { echo "$as_me:$LINENO: error: none of gcc, egcs and cc is found. set TARGET_CC manually." >&5 +echo "$as_me: error: none of gcc, egcs and cc is found. set TARGET_CC manually." >&2;} + { (exit 1); exit 1; }; }" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + TARGET_CC=$ac_ct_TARGET_CC + fi +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + { echo "$as_me:$LINENO: result: $OBJCOPY" >&5 +echo "${ECHO_T}$OBJCOPY" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + { echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5 +echo "${ECHO_T}$ac_ct_OBJCOPY" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_OBJCOPY" = x; then + OBJCOPY="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + OBJCOPY=$ac_ct_OBJCOPY + fi +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NM="nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + + + ac_tool_prefix="$tmp_ac_tool_prefix" +else + if test "x$TARGET_CC" = x; then + TARGET_CC=$CC + fi + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + { echo "$as_me:$LINENO: result: $OBJCOPY" >&5 +echo "${ECHO_T}$OBJCOPY" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + { echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5 +echo "${ECHO_T}$ac_ct_OBJCOPY" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_OBJCOPY" = x; then + OBJCOPY="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + OBJCOPY=$ac_ct_OBJCOPY + fi +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nm", so it can be a program name with args. +set dummy ${ac_tool_prefix}nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NM"; then + ac_cv_prog_NM="$NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NM="${ac_tool_prefix}nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NM=$ac_cv_prog_NM +if test -n "$NM"; then + { echo "$as_me:$LINENO: result: $NM" >&5 +echo "${ECHO_T}$NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NM"; then + ac_ct_NM=$NM + # Extract the first word of "nm", so it can be a program name with args. +set dummy nm; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NM+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NM"; then + ac_cv_prog_ac_ct_NM="$ac_ct_NM" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NM="nm" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NM=$ac_cv_prog_ac_ct_NM +if test -n "$ac_ct_NM"; then + { echo "$as_me:$LINENO: result: $ac_ct_NM" >&5 +echo "${ECHO_T}$ac_ct_NM" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NM" = x; then + NM="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + NM=$ac_ct_NM + fi +else + NM="$ac_cv_prog_NM" +fi + +fi + + + +# Test the C compiler for the target environment. +tmp_CC="$CC" +tmp_CFLAGS="$CFLAGS" +tmp_LDFLAGS="$LDFLAGS" +tmp_CPPFLAGS="$CPPFLAGS" +tmp_LIBS="$LIBS" +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS="" + +if test "x$TARGET_CFLAGS" = x; then + # debug flags. + TARGET_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \ + -Wundef -Wstrict-prototypes -g" + + # optimization flags. + { echo "$as_me:$LINENO: checking whether optimization for size works" >&5 +echo $ECHO_N "checking whether optimization for size works... $ECHO_C" >&6; } +if test "${grub_cv_cc_Os+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + CFLAGS=-Os + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + grub_cv_cc_Os=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_cc_Os=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $grub_cv_cc_Os" >&5 +echo "${ECHO_T}$grub_cv_cc_Os" >&6; } + if test "x$grub_cv_cc_Os" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -Os" + else + TARGET_CFLAGS="$TARGET_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops" + fi + + # Force no alignment to save space on i386. + if test "x$target_cpu" = xi386; then + { echo "$as_me:$LINENO: checking whether -falign-loops works" >&5 +echo $ECHO_N "checking whether -falign-loops works... $ECHO_C" >&6; } +if test "${grub_cv_cc_falign_loop+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + CFLAGS="-falign-loops=1" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + grub_cv_cc_falign_loop=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_cc_falign_loop=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ echo "$as_me:$LINENO: result: $grub_cv_cc_falign_loop" >&5 +echo "${ECHO_T}$grub_cv_cc_falign_loop" >&6; } + + if test "x$grub_cv_cc_falign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + else + TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi + fi +fi + +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" +fi + +# +# Compiler features. +# + +# Need __enable_execute_stack() for nested function trampolines? + +{ echo "$as_me:$LINENO: checking whether \`$CC' generates calls to \`__enable_execute_stack()'" >&5 +echo $ECHO_N "checking whether \`$CC' generates calls to \`__enable_execute_stack()'... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF + +void f (int (*p) (void)); +void g (int i) +{ + int nestedfunc (void) { return i; } + f (nestedfunc); +} + +_ACEOF +if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.s; then + true +else + { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5 +echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;} + { (exit 1); exit 1; }; } +fi +if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then + +cat >>confdefs.h <<\_ACEOF +#define NEED_ENABLE_EXECUTE_STACK 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi +rm -f conftest* + + +# Smashing stack protector. + +# Smashing stack protector. +ssp_possible=yes +{ echo "$as_me:$LINENO: checking whether \`$CC' accepts \`-fstack-protector'" >&5 +echo $ECHO_N "checking whether \`$CC' accepts \`-fstack-protector'... $ECHO_C" >&6; } +# Is this a reliable test case? +cat >conftest.$ac_ext <<_ACEOF +void foo (void) { volatile char a[8]; a[3]; } +_ACEOF +# `$CC -c -o ...' might not be portable. But, oh, well... Is calling +# `ac_compile' like this correct, after all? +if eval "$ac_compile -S -fstack-protector -o conftest.s" 2> /dev/null; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + # Should we clear up other files as well, having called `AC_LANG_CONFTEST'? + rm -f conftest.s +else + ssp_possible=no + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +# Need that, because some distributions ship compilers that include +# `-fstack-protector' in the default specs. +if test "x$ssp_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" +fi + +# Smashing stack arg probe. +sap_possible=yes +{ echo "$as_me:$LINENO: checking whether \`$CC' accepts \`-mstack-arg-probe'" >&5 +echo $ECHO_N "checking whether \`$CC' accepts \`-mstack-arg-probe'... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +void foo (void) { volatile char a[8]; a[3]; } +_ACEOF +if eval "$ac_compile -S -mstack-arg-probe -o conftest.s" 2> /dev/null; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + # Should we clear up other files as well, having called `AC_LANG_CONFTEST'? + rm -f conftest.s +else + sap_possible=no + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + +# Cygwin's GCC uses alloca() to probe the stackframe on static +# stack allocations above some threshold. +if test x"$sap_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + + + + + + +# Set them to their new values for the tests below. +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" + +# Defined in aclocal.m4. +{ echo "$as_me:$LINENO: checking whether target compiler is working" >&5 +echo $ECHO_N "checking whether target compiler is working... $ECHO_C" >&6; } +if test "${grub_cv_prog_target_cc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_prog_target_cc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_prog_target_cc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi + +{ echo "$as_me:$LINENO: result: $grub_cv_prog_target_cc" >&5 +echo "${ECHO_T}$grub_cv_prog_target_cc" >&6; } + +if test "x$grub_cv_prog_target_cc" = xno; then + { { echo "$as_me:$LINENO: error: cannot compile for the target" >&5 +echo "$as_me: error: cannot compile for the target" >&2;} + { (exit 1); exit 1; }; } +fi + +{ echo "$as_me:$LINENO: checking whether ${OBJCOPY} works for absolute addresses" >&5 +echo $ECHO_N "checking whether ${OBJCOPY} works for absolute addresses... $ECHO_C" >&6; } +if test "${grub_cv_prog_objcopy_absolute+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <<\EOF +void +cmain (void) +{ + *((int *) 0x1000) = 2; +} +EOF + +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && test -s conftest.o; then : +else + { { echo "$as_me:$LINENO: error: ${CC-cc} cannot compile C source code" >&5 +echo "$as_me: error: ${CC-cc} cannot compile C source code" >&2;} + { (exit 1); exit 1; }; } +fi +grub_cv_prog_objcopy_absolute=yes +for link_addr in 2000 8000 7C00; do + if { ac_try='${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then : + else + { { echo "$as_me:$LINENO: error: ${CC-cc} cannot link at address $link_addr" >&5 +echo "$as_me: error: ${CC-cc} cannot link at address $link_addr" >&2;} + { (exit 1); exit 1; }; } + fi + if { ac_try='${OBJCOPY-objcopy} --only-section=.text -O binary conftest.exec conftest' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then : + else + { { echo "$as_me:$LINENO: error: ${OBJCOPY-objcopy} cannot create binary files" >&5 +echo "$as_me: error: ${OBJCOPY-objcopy} cannot create binary files" >&2;} + { (exit 1); exit 1; }; } + fi + if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + mv -f conftest conftest.old + else + grub_cv_prog_objcopy_absolute=no + break + fi +done +rm -f conftest* +fi + +{ echo "$as_me:$LINENO: result: $grub_cv_prog_objcopy_absolute" >&5 +echo "${ECHO_T}$grub_cv_prog_objcopy_absolute" >&6; } + +if test "x$grub_cv_prog_objcopy_absolute" = xno; then + { { echo "$as_me:$LINENO: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&5 +echo "$as_me: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&2;} + { (exit 1); exit 1; }; } +fi + +{ echo "$as_me:$LINENO: checking whether linker accepts --build-id=none" >&5 +echo $ECHO_N "checking whether linker accepts --build-id=none... $ECHO_C" >&6; } +if test "${grub_cv_prog_ld_build_id_none+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS -Wl,--build-id=none" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_prog_ld_build_id_none=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_prog_ld_build_id_none=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LDFLAGS="$save_LDFLAGS" + +fi + +{ echo "$as_me:$LINENO: result: $grub_cv_prog_ld_build_id_none" >&5 +echo "${ECHO_T}$grub_cv_prog_ld_build_id_none" >&6; } + +if test "x$grub_cv_prog_ld_build_id_none" = xyes; then + MODULE_LDFLAGS="$MODULE_LDFLAGS -Wl,--build-id=none" +fi + + +{ echo "$as_me:$LINENO: checking if C symbols get an underscore after compilation" >&5 +echo $ECHO_N "checking if C symbols get an underscore after compilation... $ECHO_C" >&6; } +if test "${grub_cv_asm_uscore+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c <<\EOF +int +func (int *list) +{ + *list = 0; + return *list; +} +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.s; then + true +else + { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5 +echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;} + { (exit 1); exit 1; }; } +fi + +if grep _func conftest.s >/dev/null 2>&1; then + grub_cv_asm_uscore=yes +else + grub_cv_asm_uscore=no +fi + +rm -f conftest* +fi + + +if test "x$grub_cv_asm_uscore" = xyes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_ASM_USCORE $grub_cv_asm_uscore +_ACEOF + +fi + +{ echo "$as_me:$LINENO: result: $grub_cv_asm_uscore" >&5 +echo "${ECHO_T}$grub_cv_asm_uscore" >&6; } + +if test "x$target_cpu" = xi386; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" + fi + if test "x$platform" = xpc; then + +{ echo "$as_me:$LINENO: checking if start is defined by the compiler" >&5 +echo $ECHO_N "checking if start is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_start_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_start_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_start_symbol" >&6; } + +{ echo "$as_me:$LINENO: checking if _start is defined by the compiler" >&5 +echo $ECHO_N "checking if _start is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_uscore_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl _start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_uscore_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_uscore_start_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_start_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_uscore_start_symbol" >&6; } + + + + +if test "x$grub_cv_check_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define START_SYMBOL start +_ACEOF + +elif test "x$grub_cv_check_uscore_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define START_SYMBOL _start +_ACEOF + +else + { { echo "$as_me:$LINENO: error: neither start nor _start is defined" >&5 +echo "$as_me: error: neither start nor _start is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + +{ echo "$as_me:$LINENO: checking if __bss_start is defined by the compiler" >&5 +echo $ECHO_N "checking if __bss_start is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_uscore_uscore_bss_start_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl __bss_start") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_uscore_uscore_bss_start_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_uscore_uscore_bss_start_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_uscore_bss_start_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_uscore_uscore_bss_start_symbol" >&6; } + +{ echo "$as_me:$LINENO: checking if edata is defined by the compiler" >&5 +echo $ECHO_N "checking if edata is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_edata_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl edata") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_edata_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_edata_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_edata_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_edata_symbol" >&6; } + +{ echo "$as_me:$LINENO: checking if _edata is defined by the compiler" >&5 +echo $ECHO_N "checking if _edata is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_uscore_edata_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl _edata") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_uscore_edata_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_uscore_edata_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_edata_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_uscore_edata_symbol" >&6; } + + + + +if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL __bss_start +_ACEOF + +elif test "x$grub_cv_check_edata_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL edata +_ACEOF + +elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define BSS_START_SYMBOL _edata +_ACEOF + +else + { { echo "$as_me:$LINENO: error: none of __bss_start, edata or _edata is defined" >&5 +echo "$as_me: error: none of __bss_start, edata or _edata is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + +{ echo "$as_me:$LINENO: checking if end is defined by the compiler" >&5 +echo $ECHO_N "checking if end is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_end_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl end") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_end_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_end_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_end_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_end_symbol" >&6; } + +{ echo "$as_me:$LINENO: checking if _end is defined by the compiler" >&5 +echo $ECHO_N "checking if _end is defined by the compiler... $ECHO_C" >&6; } +if test "${grub_cv_check_uscore_end_symbol+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +asm ("incl _end") + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + grub_cv_check_uscore_end_symbol=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + grub_cv_check_uscore_end_symbol=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_check_uscore_end_symbol" >&5 +echo "${ECHO_T}$grub_cv_check_uscore_end_symbol" >&6; } + + + + +if test "x$grub_cv_check_end_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define END_SYMBOL end +_ACEOF + +elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then + cat >>confdefs.h <<\_ACEOF +#define END_SYMBOL _end +_ACEOF + +else + { { echo "$as_me:$LINENO: error: neither end nor _end is defined" >&5 +echo "$as_me: error: neither end nor _end is defined" >&2;} + { (exit 1); exit 1; }; } +fi + + fi + CFLAGS="$TARGET_CFLAGS" + +{ echo "$as_me:$LINENO: checking whether addr32 must be in the same line as the instruction" >&5 +echo $ECHO_N "checking whether addr32 must be in the same line as the instruction... $ECHO_C" >&6; } +if test "${grub_cv_i386_asm_prefix_requirement+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .code16 +l1: addr32 movb %al, l1 +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + grub_cv_i386_asm_prefix_requirement=yes +else + grub_cv_i386_asm_prefix_requirement=no +fi + +rm -f conftest* +fi + + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + grub_tmp_addr32="addr32" + grub_tmp_data32="data32" +else + grub_tmp_addr32="addr32;" + grub_tmp_data32="data32;" +fi + + +cat >>confdefs.h <<_ACEOF +#define ADDR32 $grub_tmp_addr32 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define DATA32 $grub_tmp_data32 +_ACEOF + + +{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_prefix_requirement" >&5 +echo "${ECHO_T}$grub_cv_i386_asm_prefix_requirement" >&6; } + + +{ echo "$as_me:$LINENO: checking for .code16 addr32 assembler support" >&5 +echo $ECHO_N "checking for .code16 addr32 assembler support... $ECHO_C" >&6; } +if test "${grub_cv_i386_asm_addr32+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s.in <<\EOF + .code16 +l1: @ADDR32@ movb %al, l1 +EOF + +if test "x$grub_cv_i386_asm_prefix_requirement" = xyes; then + sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s +else + sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s +fi + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + grub_cv_i386_asm_addr32=yes +else + grub_cv_i386_asm_addr32=no +fi + +rm -f conftest* +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_addr32" >&5 +echo "${ECHO_T}$grub_cv_i386_asm_addr32" >&6; } + +{ echo "$as_me:$LINENO: checking whether an absolute indirect call/jump must not be prefixed with an asterisk" >&5 +echo $ECHO_N "checking whether an absolute indirect call/jump must not be prefixed with an asterisk... $ECHO_C" >&6; } +if test "${grub_cv_i386_asm_absolute_without_asterisk+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + lcall *(offset) +offset: + .long 0 + .word 0 +EOF + +if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && test -s conftest.o; then + grub_cv_i386_asm_absolute_without_asterisk=no +else + grub_cv_i386_asm_absolute_without_asterisk=yes +fi + +rm -f conftest* +fi + + +if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define ABSOLUTE_WITHOUT_ASTERISK 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: result: $grub_cv_i386_asm_absolute_without_asterisk" >&5 +echo "${ECHO_T}$grub_cv_i386_asm_absolute_without_asterisk" >&6; } + +{ echo "$as_me:$LINENO: checking if GCC has the regparm=3 bug" >&5 +echo $ECHO_N "checking if GCC has the regparm=3 bug... $ECHO_C" >&6; } +if test "${grub_cv_i386_check_nested_functions+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +static int +test (int *n) +{ + return *n == -1; +} + +static int +testfunc (int __attribute__ ((__regparm__ (3))) (*hook) (int a, int b, int *c)) +{ + int a = 0; + int b = 0; + int c = -1; + return hook (a, b, &c); +} + +int +main (void) +{ + int __attribute__ ((__regparm__ (3))) nestedfunc (int a, int b, int *c) + { + return a == b && test (c); + } + return testfunc (nestedfunc) ? 0 : 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + grub_cv_i386_check_nested_functions=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +grub_cv_i386_check_nested_functions=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + + +{ echo "$as_me:$LINENO: result: $grub_cv_i386_check_nested_functions" >&5 +echo "${ECHO_T}$grub_cv_i386_check_nested_functions" >&6; } + +if test "x$grub_cv_i386_check_nested_functions" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) +_ACEOF + +fi + +else + +cat >>confdefs.h <<\_ACEOF +#define NESTED_FUNC_ATTR +_ACEOF + +fi + +# Restore the flags. +CC="$tmp_CC" +CFLAGS="$tmp_CFLAGS" +CPPFLAGS="$tmp_CPPFLAGS" +LDFLAGS="$tmp_LDFLAGS" +LIBS="$tmp_LIBS" + +# +# Check for options. +# + +# Memory manager debugging. +# Check whether --enable-mm-debug was given. +if test "${enable_mm_debug+set}" = set; then + enableval=$enable_mm_debug; +cat >>confdefs.h <<\_ACEOF +#define MM_DEBUG 1 +_ACEOF + +fi + + +# Check whether --enable-grub-emu was given. +if test "${enable_grub_emu+set}" = set; then + enableval=$enable_grub_emu; +fi + +# Check whether --enable-grub-emu-usb was given. +if test "${enable_grub_emu_usb+set}" = set; then + enableval=$enable_grub_emu_usb; +fi + +if [ x"$enable_grub_emu" = xyes ]; then + # Check for curses libraries. + { echo "$as_me:$LINENO: checking for wgetch in -lncurses" >&5 +echo $ECHO_N "checking for wgetch in -lncurses... $ECHO_C" >&6; } +if test "${ac_cv_lib_ncurses_wgetch+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char wgetch (); +int +main () +{ +return wgetch (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_ncurses_wgetch=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ncurses_wgetch=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_wgetch" >&5 +echo "${ECHO_T}$ac_cv_lib_ncurses_wgetch" >&6; } +if test $ac_cv_lib_ncurses_wgetch = yes; then + LIBCURSES="-lncurses" +else + { echo "$as_me:$LINENO: checking for wgetch in -lcurses" >&5 +echo $ECHO_N "checking for wgetch in -lcurses... $ECHO_C" >&6; } +if test "${ac_cv_lib_curses_wgetch+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcurses $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char wgetch (); +int +main () +{ +return wgetch (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_curses_wgetch=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_curses_wgetch=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_curses_wgetch" >&5 +echo "${ECHO_T}$ac_cv_lib_curses_wgetch" >&6; } +if test $ac_cv_lib_curses_wgetch = yes; then + LIBCURSES="-lcurses" +else + { { echo "$as_me:$LINENO: error: (n)curses libraries are required to build \`grub-emu'" >&5 +echo "$as_me: error: (n)curses libraries are required to build \`grub-emu'" >&2;} + { (exit 1); exit 1; }; } +fi + +fi + + + + # Check for headers. + +for ac_header in ncurses/curses.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------- ## +## Report this to bug-grub@gnu.org ## +## ------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + +for ac_header in ncurses.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------- ## +## Report this to bug-grub@gnu.org ## +## ------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + +for ac_header in curses.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------- ## +## Report this to bug-grub@gnu.org ## +## ------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: (n)curses header files are required to build \`grub-emu'" >&5 +echo "$as_me: error: (n)curses header files are required to build \`grub-emu'" >&2;} + { (exit 1); exit 1; }; } +fi + +done + +fi + +done + +fi + +done + + + if [ x"$enable_grub_emu_usb" = xyes ]; then + # Check for libusb libraries. + { echo "$as_me:$LINENO: checking for usb_claim_interface in -lusb" >&5 +echo $ECHO_N "checking for usb_claim_interface in -lusb... $ECHO_C" >&6; } +if test "${ac_cv_lib_usb_usb_claim_interface+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lusb $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char usb_claim_interface (); +int +main () +{ +return usb_claim_interface (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_usb_usb_claim_interface=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_usb_usb_claim_interface=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_usb_usb_claim_interface" >&5 +echo "${ECHO_T}$ac_cv_lib_usb_usb_claim_interface" >&6; } +if test $ac_cv_lib_usb_usb_claim_interface = yes; then + LIBUSB="-lusb" +else + { { echo "$as_me:$LINENO: error: libusb libraries are required to build \`grub-emu' with USB support" >&5 +echo "$as_me: error: libusb libraries are required to build \`grub-emu' with USB support" >&2;} + { (exit 1); exit 1; }; } +fi + + + + # Check for headers. + +for ac_header in usb.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------- ## +## Report this to bug-grub@gnu.org ## +## ------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +else + { { echo "$as_me:$LINENO: error: libusb header file is required to build \`grub-emu' with USB support" >&5 +echo "$as_me: error: libusb header file is required to build \`grub-emu' with USB support" >&2;} + { (exit 1); exit 1; }; } +fi + +done + + fi +fi + + + +# Check whether --enable-grub-fstest was given. +if test "${enable_grub_fstest+set}" = set; then + enableval=$enable_grub_fstest; +fi + + + +# Check whether --enable-grub-pe2elf was given. +if test "${enable_grub_pe2elf+set}" = set; then + enableval=$enable_grub_pe2elf; +fi + + + +# Check whether --enable-grub-mkfont was given. +if test "${enable_grub_mkfont+set}" = set; then + enableval=$enable_grub_mkfont; +fi + +if test x"$enable_grub_mkfont" = xyes ; then + # Check for freetype libraries. + for ac_prog in freetype-config +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_FREETYPE+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$FREETYPE"; then + ac_cv_prog_FREETYPE="$FREETYPE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_FREETYPE="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +FREETYPE=$ac_cv_prog_FREETYPE +if test -n "$FREETYPE"; then + { echo "$as_me:$LINENO: result: $FREETYPE" >&5 +echo "${ECHO_T}$FREETYPE" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$FREETYPE" && break +done + + if test "x$FREETYPE" = x ; then + { { echo "$as_me:$LINENO: error: freetype2 libraries are required to build \`grub-mkfont'" >&5 +echo "$as_me: error: freetype2 libraries are required to build \`grub-mkfont'" >&2;} + { (exit 1); exit 1; }; } + fi + freetype_cflags=`freetype-config --cflags` + freetype_libs=`freetype-config --libs` +fi + + + + +# Output files. +ac_config_links="$ac_config_links include/grub/cpu:include/grub/$target_cpu include/grub/machine:include/grub/$target_cpu/$platform" + +ac_config_files="$ac_config_files Makefile gensymlist.sh genkernsyms.sh" + +ac_config_files="$ac_config_files stamp-h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GRUB $as_me 1.96, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_links="$ac_config_links" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration links: +$config_links + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +GRUB config.status 1.96 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "include/grub/cpu") CONFIG_LINKS="$CONFIG_LINKS include/grub/cpu:include/grub/$target_cpu" ;; + "include/grub/machine") CONFIG_LINKS="$CONFIG_LINKS include/grub/machine:include/grub/$target_cpu/$platform" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "gensymlist.sh") CONFIG_FILES="$CONFIG_FILES gensymlist.sh" ;; + "genkernsyms.sh") CONFIG_FILES="$CONFIG_FILES genkernsyms.sh" ;; + "stamp-h") CONFIG_FILES="$CONFIG_FILES stamp-h" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +platform!$platform$ac_delim +CMP!$CMP$ac_delim +YACC!$YACC$ac_delim +UNIFONT_BDF!$UNIFONT_BDF$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +RUBY!$RUBY$ac_delim +HELP2MAN!$HELP2MAN$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBLZO!$LIBLZO$ac_delim +enable_lzo!$enable_lzo$ac_delim +TARGET_IMG_LDSCRIPT!$TARGET_IMG_LDSCRIPT$ac_delim +TARGET_IMG_LDFLAGS!$TARGET_IMG_LDFLAGS$ac_delim +TARGET_OBJ2ELF!$TARGET_OBJ2ELF$ac_delim +TARGET_CC!$TARGET_CC$ac_delim +ac_ct_TARGET_CC!$ac_ct_TARGET_CC$ac_delim +OBJCOPY!$OBJCOPY$ac_delim +STRIP!$STRIP$ac_delim +NM!$NM$ac_delim +TARGET_CFLAGS!$TARGET_CFLAGS$ac_delim +TARGET_CPPFLAGS!$TARGET_CPPFLAGS$ac_delim +TARGET_LDFLAGS!$TARGET_LDFLAGS$ac_delim +MODULE_LDFLAGS!$MODULE_LDFLAGS$ac_delim +LIBCURSES!$LIBCURSES$ac_delim +LIBUSB!$LIBUSB$ac_delim +enable_grub_emu!$enable_grub_emu$ac_delim +enable_grub_emu_usb!$enable_grub_emu_usb$ac_delim +enable_grub_fstest!$enable_grub_fstest$ac_delim +enable_grub_pe2elf!$enable_grub_pe2elf$ac_delim +FREETYPE!$FREETYPE$ac_delim +enable_grub_mkfont!$enable_grub_mkfont$ac_delim +freetype_cflags!$freetype_cflags$ac_delim +freetype_libs!$freetype_libs$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed 's/|#_!!_#|//g' >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + :L) + # + # CONFIG_LINK + # + + { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: linking $srcdir/$ac_source to $ac_file" >&6;} + + if test ! -r "$srcdir/$ac_source"; then + { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 +echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} + { (exit 1); exit 1; }; } + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$srcdir/$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$srcdir/$ac_source" "$ac_file" 2>/dev/null || + cp -p "$srcdir/$ac_source" "$ac_file" || + { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&5 +echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + + esac + + + case $ac_file$ac_mode in + "stamp-h":F) echo timestamp > stamp-h ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..7658c7a --- /dev/null +++ b/configure.ac @@ -0,0 +1,444 @@ +# Process this file with autoconf to produce a configure script. + +# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +# +# This configure.ac is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl This configure script is complicated, because GRUB needs to deal +dnl with three potentially different types: +dnl +dnl build -- the environment for building GRUB +dnl host -- the environment for running utilities +dnl target -- the environment for running GRUB +dnl +dnl In addition, GRUB needs to deal with a platform specification +dnl which specifies the system running GRUB, such as firmware. +dnl This is necessary because the target type in autoconf does not +dnl describe such a system very well. +dnl +dnl The current strategy is to use variables with no prefix (such as +dnl CC, CFLAGS, etc.) for the host type as well as the build type, +dnl because GRUB does not need to use those variables for the build +dnl type, so there is no conflict. Variables with the prefix "TARGET_" +dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target +dnl type. + + +AC_INIT([GRUB],[1.96],[bug-grub@gnu.org]) +AC_PREREQ(2.59) +AC_CONFIG_SRCDIR([include/grub/dl.h]) +AC_CONFIG_HEADER([config.h]) + +# Checks for host and target systems. +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +# Program name transformations +AC_ARG_PROGRAM + +case "$host_cpu" in + powerpc64) host_m32=1 ;; +esac + +case "$target_cpu" in + i[[3456]]86) target_cpu=i386 ;; +esac + +# Specify the platform (such as firmware). +AC_ARG_WITH([platform], + AS_HELP_STRING([--with-platform=PLATFORM], + [select the host platform [[guessed]]])) + +# Guess the platform if not specified. +if test "x$with_platform" = x; then + case "$target_cpu"-"$target_vendor" in + i386-apple) platform=efi ;; + i386-*) platform=pc ;; + x86_64-apple) platform=efi ;; + x86_64-*) platform=pc ;; + powerpc-*) platform=ieee1275 ;; + powerpc64-*) platform=ieee1275 ;; + sparc64-*) platform=ieee1275 ;; + *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; + esac +else + platform="$with_platform" +fi + +# Adjust CPU unless target was explicitly specified. +if test -z "$target_alias"; then + case "$target_cpu"-"$platform" in + x86_64-efi) ;; + x86_64-*) target_cpu=i386 ;; + powerpc64-ieee1275) target_cpu=powerpc ;; + esac +fi + +# Check if the platform is supported, make final adjustments. +case "$target_cpu"-"$platform" in + i386-efi) ;; + x86_64-efi) ;; + i386-pc) ;; + i386-coreboot) ;; + i386-linuxbios) platform=coreboot ;; + i386-ieee1275) ;; + powerpc-ieee1275) ;; + sparc64-ieee1275) ;; + *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; +esac + +case "$target_cpu" in + i386 | powerpc) target_m32=1 ;; + x86_64 | sparc64) target_m64=1 ;; +esac + +case "$host_os" in + mingw32) host_os=cygwin ;; +esac + +AC_SUBST(host_cpu) +AC_SUBST(host_os) + +AC_SUBST(target_cpu) +AC_SUBST(platform) + +# +# Checks for build programs. +# + +# Although cmp is listed in the GNU Coding Standards as a command which +# can used directly, OpenBSD lacks cmp in the default installation. +AC_CHECK_PROGS([CMP], [cmp]) +if test "x$CMP" = x; then + AC_MSG_ERROR([cmp is not found]) +fi + +AC_CHECK_PROGS([YACC], [bison]) +if test "x$YACC" = x; then + AC_MSG_ERROR([bison is not found]) +fi + +for file in /usr/src/unifont.bdf ; do + if test -e $file ; then + AC_SUBST([UNIFONT_BDF], [$file]) + break + fi +done + +AC_PROG_INSTALL +AC_PROG_AWK +AC_PROG_MAKE_SET + +# These are not a "must". +AC_PATH_PROG(RUBY, ruby) +AC_PATH_PROG(HELP2MAN, help2man) + +# +# Checks for host programs. +# + +AC_PROG_CC +# Must be GCC. +test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required]) + +AC_GNU_SOURCE +AC_SYS_LARGEFILE + +# Identify characteristics of the host architecture. +AC_C_BIGENDIAN +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) + +if test "x$host_m32" = x1; then + # Force 32-bit mode. + CFLAGS="$CFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" +fi + +# Check LZO when compiling for the i386-pc. +if test "$target_cpu"-"$platform" = i386-pc; then + AC_ARG_ENABLE([lzo], + [AS_HELP_STRING([--enable-lzo], + [use lzo to compress kernel (default is lzma)])]) + [if [ x"$enable_lzo" = xyes ]; then + # There are three possibilities. LZO version 2 installed with the name + # liblzo2, with the name liblzo, and LZO version 1.] + AC_DEFINE([ENABLE_LZO], [1], [Use lzo compression]) + AC_CHECK_LIB([lzo2], [__lzo_init_v2], [LIBLZO="-llzo2"], + [AC_CHECK_LIB([lzo], [__lzo_init_v2], [LIBLZO="-llzo"], + [AC_CHECK_LIB([lzo], [__lzo_init2], [LIBLZO="-llzo"], + [AC_MSG_ERROR([LZO library version 1.02 or later is required])])])]) + AC_SUBST([LIBLZO]) + [LIBS="$LIBS $LIBLZO"] + AC_CHECK_FUNC([lzo1x_999_compress], , + [AC_MSG_ERROR([LZO1X-999 must be enabled])]) + + [# LZO version 2 uses lzo/lzo1x.h, while LZO version 1 uses lzo1x.h.] + AC_CHECK_HEADERS([lzo/lzo1x.h lzo1x.h]) + [else] + AC_DEFINE([ENABLE_LZMA], [1], [Use lzma compression]) + [fi] + AC_SUBST([enable_lzo]) +fi + +# Check for functions. +AC_CHECK_FUNCS(posix_memalign memalign asprintf) + +# +# Check for target programs. +# + + +# Use linker script if present, otherwise use builtin -N script. +AC_MSG_CHECKING([for option to link raw image]) +if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" +else + TARGET_IMG_LDSCRIPT= + TARGET_IMG_LDFLAGS='-Wl,-N' + TARGET_IMG_LDFLAGS_AC='-Wl,-N' +fi +AC_SUBST(TARGET_IMG_LDSCRIPT) +AC_SUBST(TARGET_IMG_LDFLAGS) +AC_MSG_RESULT([$TARGET_IMG_LDFLAGS_AC]) + +# For platforms where ELF is not the default link format. +AC_MSG_CHECKING([for command to convert module to ELF format]) +case "${host_os}" in + cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;; + *) ;; +esac +AC_SUBST(TARGET_OBJ2ELF) +AC_MSG_RESULT([$TARGET_OBJ2ELF]) + +# For cross-compiling. +if test "x$build" != "x$host"; then + # XXX this depends on the implementation of autoconf! + tmp_ac_tool_prefix="$ac_tool_prefix" + ac_tool_prefix=$target_alias- + + AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc], + [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])]) + AC_CHECK_TOOL(OBJCOPY, objcopy) + AC_CHECK_TOOL(STRIP, strip) + AC_CHECK_TOOL(NM, nm) + + ac_tool_prefix="$tmp_ac_tool_prefix" +else + if test "x$TARGET_CC" = x; then + TARGET_CC=$CC + fi + AC_CHECK_TOOL(OBJCOPY, objcopy) + AC_CHECK_TOOL(STRIP, strip) + AC_CHECK_TOOL(NM, nm) +fi +AC_SUBST(TARGET_CC) + + +# Test the C compiler for the target environment. +tmp_CC="$CC" +tmp_CFLAGS="$CFLAGS" +tmp_LDFLAGS="$LDFLAGS" +tmp_CPPFLAGS="$CPPFLAGS" +tmp_LIBS="$LIBS" +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS="" + +if test "x$TARGET_CFLAGS" = x; then + # debug flags. + TARGET_CFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes \ + -Wundef -Wstrict-prototypes -g" + + # optimization flags. + AC_CACHE_CHECK([whether optimization for size works], grub_cv_cc_Os, [ + CFLAGS=-Os + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_Os=yes], + [grub_cv_cc_Os=no]) + ]) + if test "x$grub_cv_cc_Os" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -Os" + else + TARGET_CFLAGS="$TARGET_CFLAGS -O2 -fno-strength-reduce -fno-unroll-loops" + fi + + # Force no alignment to save space on i386. + if test "x$target_cpu" = xi386; then + AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ + CFLAGS="-falign-loops=1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_falign_loop=yes], + [grub_cv_cc_falign_loop=no]) + ]) + + if test "x$grub_cv_cc_falign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + else + TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi + fi +fi + +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" +fi + +# +# Compiler features. +# + +# Need __enable_execute_stack() for nested function trampolines? +grub_CHECK_ENABLE_EXECUTE_STACK + +# Smashing stack protector. +grub_CHECK_STACK_PROTECTOR +# Need that, because some distributions ship compilers that include +# `-fstack-protector' in the default specs. +if test "x$ssp_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" +fi +grub_CHECK_STACK_ARG_PROBE +# Cygwin's GCC uses alloca() to probe the stackframe on static +# stack allocations above some threshold. +if test x"$sap_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + +AC_SUBST(TARGET_CFLAGS) +AC_SUBST(TARGET_CPPFLAGS) +AC_SUBST(TARGET_LDFLAGS) +AC_SUBST(MODULE_LDFLAGS) + +# Set them to their new values for the tests below. +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" + +# Defined in aclocal.m4. +grub_PROG_TARGET_CC +grub_PROG_OBJCOPY_ABSOLUTE +grub_PROG_LD_BUILD_ID_NONE +grub_ASM_USCORE +if test "x$target_cpu" = xi386; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" + fi + if test "x$platform" = xpc; then + grub_CHECK_START_SYMBOL + grub_CHECK_BSS_START_SYMBOL + grub_CHECK_END_SYMBOL + fi + CFLAGS="$TARGET_CFLAGS" + grub_I386_ASM_PREFIX_REQUIREMENT + grub_I386_ASM_ADDR32 + grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK + grub_I386_CHECK_REGPARM_BUG +else + AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug]) +fi + +# Restore the flags. +CC="$tmp_CC" +CFLAGS="$tmp_CFLAGS" +CPPFLAGS="$tmp_CPPFLAGS" +LDFLAGS="$tmp_LDFLAGS" +LIBS="$tmp_LIBS" + +# +# Check for options. +# + +# Memory manager debugging. +AC_ARG_ENABLE([mm-debug], + AS_HELP_STRING([--enable-mm-debug], + [include memory manager debugging]), + [AC_DEFINE([MM_DEBUG], [1], + [Define to 1 if you enable memory manager debugging.])]) + +AC_ARG_ENABLE([grub-emu], + [AS_HELP_STRING([--enable-grub-emu], + [build and install the `grub-emu' debugging utility])]) +AC_ARG_ENABLE([grub-emu-usb], + [AS_HELP_STRING([--enable-grub-emu-usb], + [build and install the `grub-emu' debugging utility with USB support])]) +[if [ x"$enable_grub_emu" = xyes ]; then + # Check for curses libraries.] + AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"], + [AC_CHECK_LIB([curses], [wgetch], [LIBCURSES="-lcurses"], + [AC_MSG_ERROR([(n)curses libraries are required to build `grub-emu'])])]) + AC_SUBST([LIBCURSES]) + + [# Check for headers.] + AC_CHECK_HEADERS([ncurses/curses.h], [], + [AC_CHECK_HEADERS([ncurses.h], [], + [AC_CHECK_HEADERS([curses.h], [], + [AC_MSG_ERROR([(n)curses header files are required to build `grub-emu'])])])]) + + [if [ x"$enable_grub_emu_usb" = xyes ]; then + # Check for libusb libraries.] + AC_CHECK_LIB([usb], [usb_claim_interface], [LIBUSB="-lusb"], + [AC_MSG_ERROR([libusb libraries are required to build `grub-emu' with USB support])]) + AC_SUBST([LIBUSB]) + + [# Check for headers.] + AC_CHECK_HEADERS([usb.h], [], + [AC_MSG_ERROR([libusb header file is required to build `grub-emu' with USB support])]) + [fi] +[fi] +AC_SUBST([enable_grub_emu]) +AC_SUBST([enable_grub_emu_usb]) + +AC_ARG_ENABLE([grub-fstest], + [AS_HELP_STRING([--enable-grub-fstest], + [build and install the `grub-fstest' debugging utility])]) +AC_SUBST([enable_grub_fstest]) + +AC_ARG_ENABLE([grub-pe2elf], + [AS_HELP_STRING([--enable-grub-pe2elf], + [build and install the `grub-pe2elf' conversion utility])]) +AC_SUBST([enable_grub_pe2elf]) + +AC_ARG_ENABLE([grub-mkfont], + [AS_HELP_STRING([--enable-grub-mkfont], + [build and install the `grub-mkfont' utility])]) +if test x"$enable_grub_mkfont" = xyes ; then + # Check for freetype libraries. + AC_CHECK_PROGS([FREETYPE], [freetype-config]) + if test "x$FREETYPE" = x ; then + AC_MSG_ERROR([freetype2 libraries are required to build `grub-mkfont']) + fi + freetype_cflags=`freetype-config --cflags` + freetype_libs=`freetype-config --libs` +fi +AC_SUBST([enable_grub_mkfont]) +AC_SUBST([freetype_cflags]) +AC_SUBST([freetype_libs]) + +# Output files. +AC_CONFIG_LINKS([include/grub/cpu:include/grub/$target_cpu + include/grub/machine:include/grub/$target_cpu/$platform]) +AC_CONFIG_FILES([Makefile gensymlist.sh genkernsyms.sh]) +AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +AC_OUTPUT diff --git a/disk/ata.c b/disk/ata.c new file mode 100644 index 0000000..ed98b0b --- /dev/null +++ b/disk/ata.c @@ -0,0 +1,861 @@ +/* ata.c - ATA disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* At the moment, only two IDE ports are supported. */ +static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 }; +static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; + +static struct grub_ata_device *grub_ata_devices; + +/* Wait for !BSY. */ +grub_err_t +grub_ata_wait_not_busy (struct grub_ata_device *dev, int milliseconds) +{ + /* ATA requires 400ns (after a write to CMD register) or + 1 PIO cycle (after a DRQ block transfer) before + first check of BSY. */ + grub_millisleep (1); + + int i = 1; + while (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + { + if (i >= milliseconds) + { + grub_dprintf ("ata", "timeout: %dms\n", milliseconds); + return grub_error (GRUB_ERR_TIMEOUT, "ATA timeout"); + } + + grub_millisleep (1); + i++; + } + + return GRUB_ERR_NONE; +} + +static inline void +grub_ata_wait (void) +{ + grub_millisleep (50); +} + +/* Wait for !BSY, DRQ. */ +grub_err_t +grub_ata_wait_drq (struct grub_ata_device *dev, int rw, + int milliseconds) +{ + if (grub_ata_wait_not_busy (dev, milliseconds)) + return grub_errno; + + /* !DRQ implies error condition. */ + grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + != GRUB_ATA_STATUS_DRQ) + { + grub_dprintf ("ata", "ata error: status=0x%x, error=0x%x\n", + sts, grub_ata_regget (dev, GRUB_ATA_REG_ERROR)); + if (! rw) + return grub_error (GRUB_ERR_READ_ERROR, "ATA read error"); + else + return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); + } + + return GRUB_ERR_NONE; +} + +/* Byteorder has to be changed before strings can be read. */ +static void +grub_ata_strncpy (char *dst, char *src, grub_size_t len) +{ + grub_uint16_t *src16 = (grub_uint16_t *) src; + grub_uint16_t *dst16 = (grub_uint16_t *) dst; + unsigned int i; + + for (i = 0; i < len / 2; i++) + *(dst16++) = grub_be_to_cpu16 (*(src16++)); + dst[len] = '\0'; +} + +void +grub_ata_pio_read (struct grub_ata_device *dev, char *buf, grub_size_t size) +{ + grub_uint16_t *buf16 = (grub_uint16_t *) buf; + unsigned int i; + + /* Read in the data, word by word. */ + for (i = 0; i < size / 2; i++) + buf16[i] = grub_le_to_cpu16 (grub_inw(dev->ioaddress + GRUB_ATA_REG_DATA)); +} + +static void +grub_ata_pio_write (struct grub_ata_device *dev, char *buf, grub_size_t size) +{ + grub_uint16_t *buf16 = (grub_uint16_t *) buf; + unsigned int i; + + /* Write the data, word by word. */ + for (i = 0; i < size / 2; i++) + grub_outw(grub_cpu_to_le16 (buf16[i]), dev->ioaddress + GRUB_ATA_REG_DATA); +} + +static void +grub_ata_dumpinfo (struct grub_ata_device *dev, char *info) +{ + char text[41]; + + /* The device information was read, dump it for debugging. */ + grub_ata_strncpy (text, info + 20, 20); + grub_dprintf ("ata", "Serial: %s\n", text); + grub_ata_strncpy (text, info + 46, 8); + grub_dprintf ("ata", "Firmware: %s\n", text); + grub_ata_strncpy (text, info + 54, 40); + grub_dprintf ("ata", "Model: %s\n", text); + + if (! dev->atapi) + { + grub_dprintf ("ata", "Addressing: %d\n", dev->addr); + grub_dprintf ("ata", "Sectors: %lld\n", dev->size); + } +} + +static grub_err_t +grub_atapi_identify (struct grub_ata_device *dev) +{ + char *info; + + info = grub_malloc (GRUB_DISK_SECTOR_SIZE); + if (! info) + return grub_errno; + + grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); + if (grub_ata_check_ready (dev)) + { + grub_free (info); + return grub_errno; + } + + grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE); + grub_ata_wait (); + + if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) + { + grub_free (info); + return grub_errno; + } + grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); + + dev->atapi = 1; + + grub_ata_dumpinfo (dev, info); + + grub_free (info); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_atapi_wait_drq (struct grub_ata_device *dev, + grub_uint8_t ireason, + int milliseconds) +{ + /* Wait for !BSY, DRQ, ireason */ + if (grub_ata_wait_not_busy (dev, milliseconds)) + return grub_errno; + + grub_uint8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + grub_uint8_t irs = grub_ata_regget (dev, GRUB_ATAPI_REG_IREASON); + + /* OK if DRQ is asserted and interrupt reason is as expected. */ + if ((sts & GRUB_ATA_STATUS_DRQ) + && (irs & GRUB_ATAPI_IREASON_MASK) == ireason) + return GRUB_ERR_NONE; + + /* !DRQ implies error condition. */ + grub_dprintf ("ata", "atapi error: status=0x%x, ireason=0x%x, error=0x%x\n", + sts, irs, grub_ata_regget (dev, GRUB_ATA_REG_ERROR)); + + if (! (sts & GRUB_ATA_STATUS_DRQ) + && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_ERROR) + { + if (ireason == GRUB_ATAPI_IREASON_CMD_OUT) + return grub_error (GRUB_ERR_READ_ERROR, "ATA PACKET command error"); + else + return grub_error (GRUB_ERR_READ_ERROR, "ATAPI read error"); + } + + return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error"); +} + +static grub_err_t +grub_atapi_packet (struct grub_ata_device *dev, char *packet, + grub_size_t size) +{ + grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); + if (grub_ata_check_ready (dev)) + return grub_errno; + + /* Send ATA PACKET command. */ + grub_ata_regset (dev, GRUB_ATA_REG_FEATURES, 0); + grub_ata_regset (dev, GRUB_ATAPI_REG_IREASON, 0); + grub_ata_regset (dev, GRUB_ATAPI_REG_CNTHIGH, size >> 8); + grub_ata_regset (dev, GRUB_ATAPI_REG_CNTLOW, size & 0xFF); + + grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_PACKET); + + /* Wait for !BSY, DRQ, !I/O, C/D. */ + if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_CMD_OUT, GRUB_ATA_TOUT_STD)) + return grub_errno; + + /* Write the packet. */ + grub_ata_pio_write (dev, packet, 12); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ata_identify (struct grub_ata_device *dev) +{ + char *info; + grub_uint16_t *info16; + + info = grub_malloc (GRUB_DISK_SECTOR_SIZE); + if (! info) + return grub_errno; + + info16 = (grub_uint16_t *) info; + + grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4); + if (grub_ata_check_ready (dev)) + { + grub_free (info); + return grub_errno; + } + + grub_ata_regset (dev, GRUB_ATA_REG_CMD, GRUB_ATA_CMD_IDENTIFY_DEVICE); + grub_ata_wait (); + + if (grub_ata_wait_drq (dev, 0, GRUB_ATA_TOUT_STD)) + { + if (grub_ata_regget (dev, GRUB_ATA_REG_ERROR) & 0x04) /* ABRT */ + { + /* Device without ATA IDENTIFY, try ATAPI. */ + grub_free(info); + grub_errno = GRUB_ERR_NONE; + return grub_atapi_identify (dev); + } + else + { + /* Error. */ + grub_free(info); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "device can not be identified"); + } + } + + grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); + + /* Now it is certain that this is not an ATAPI device. */ + dev->atapi = 0; + + /* CHS is always supported. */ + dev->addr = GRUB_ATA_CHS; + + /* Check if LBA is supported. */ + if (info16[49] & (1 << 9)) + { + /* Check if LBA48 is supported. */ + if (info16[83] & (1 << 10)) + dev->addr = GRUB_ATA_LBA48; + else + dev->addr = GRUB_ATA_LBA; + } + + /* Determine the amount of sectors. */ + if (dev->addr != GRUB_ATA_LBA48) + dev->size = grub_le_to_cpu32(*((grub_uint32_t *) &info16[60])); + else + dev->size = grub_le_to_cpu64(*((grub_uint64_t *) &info16[100])); + + /* Read CHS information. */ + dev->cylinders = info16[1]; + dev->heads = info16[3]; + dev->sectors_per_track = info16[6]; + + grub_ata_dumpinfo (dev, info); + + grub_free(info); + + return 0; +} + +static grub_err_t +grub_ata_device_initialize (int port, int device, int addr, int addr2) +{ + struct grub_ata_device *dev; + struct grub_ata_device **devp; + + grub_dprintf ("ata", "detecting device %d,%d (0x%x, 0x%x)\n", + port, device, addr, addr2); + + dev = grub_malloc (sizeof(*dev)); + if (! dev) + return grub_errno; + + /* Setup the device information. */ + dev->port = port; + dev->device = device; + dev->ioaddress = addr; + dev->ioaddress2 = addr2; + dev->next = NULL; + + grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); + grub_ata_wait (); + + /* If status is 0x00, it is safe to assume that there + is no device (or only a !READY) device connected. */ + grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + grub_dprintf ("ata", "status=0x%x\n", sts); + if (sts == 0x00) + { + grub_free(dev); + return 0; + } + + /* Try to detect if the port is in use by writing to it, + waiting for a while and reading it again. If the value + was preserved, there is a device connected. + But this tests often detects a second (slave) device + connected to a SATA controller which supports only one + (master) device. In this case, the status register + check above usually works. */ + grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A); + grub_ata_wait (); + grub_int8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS); + grub_dprintf ("ata", "sectors=0x%x\n", sec); + if (sec != 0x5A) + { + grub_free(dev); + return 0; + } + + /* Use the IDENTIFY DEVICE command to query the device. */ + if (grub_ata_identify (dev)) + { + grub_free (dev); + return 0; + } + + /* Register the device. */ + for (devp = &grub_ata_devices; *devp; devp = &(*devp)->next); + *devp = dev; + + return 0; +} + +static int +grub_ata_pciinit (int bus, int device, int func, + grub_pci_id_t pciid __attribute__((unused))) +{ + static int compat_use[2] = { 0 }; + grub_pci_address_t addr; + grub_uint32_t class; + grub_uint32_t bar1; + grub_uint32_t bar2; + int rega; + int regb; + int i; + static int controller = 0; + + /* Read class. */ + addr = grub_pci_make_address (bus, device, func, 2); + class = grub_pci_read (addr); + + /* Check if this class ID matches that of a PCI IDE Controller. */ + if (class >> 16 != 0x0101) + return 0; + + for (i = 0; i < 2; i++) + { + /* Set to 0 when the channel operated in compatibility mode. */ + int compat = (class >> (8 + 2 * i)) & 1; + + rega = 0; + regb = 0; + + /* If the channel is in compatibility mode, just assign the + default registers. */ + if (compat == 0 && !compat_use[i]) + { + rega = grub_ata_ioaddress[i]; + regb = grub_ata_ioaddress2[i]; + compat_use[i] = 1; + } + else if (compat) + { + /* Read the BARs, which either contain a mmapped IO address + or the IO port address. */ + addr = grub_pci_make_address (bus, device, func, 4 + 2 * i); + bar1 = grub_pci_read (addr); + addr = grub_pci_make_address (bus, device, func, 5 + 2 * i); + bar2 = grub_pci_read (addr); + + /* Check if the BARs describe an IO region. */ + if ((bar1 & 1) && (bar2 & 1)) + { + rega = bar1 & ~3; + regb = bar2 & ~3; + } + } + + grub_dprintf ("ata", + "PCI dev (%d,%d,%d) compat=%d rega=0x%x regb=0x%x\n", + bus, device, func, compat, rega, regb); + + if (rega && regb) + { + grub_errno = GRUB_ERR_NONE; + grub_ata_device_initialize (controller * 2 + i, 0, rega, regb); + + /* Most errors rised by grub_ata_device_initialize() are harmless. + They just indicate this particular drive is not responding, most + likely because it doesn't exist. We might want to ignore specific + error types here, instead of printing them. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_ata_device_initialize (controller * 2 + i, 1, rega, regb); + + /* Likewise. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + } + } + + controller++; + + return 0; +} + +static grub_err_t +grub_ata_initialize (void) +{ + grub_pci_iterate (grub_ata_pciinit); + return 0; +} + + +static void +grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector, + grub_size_t size) +{ + grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, size); + grub_ata_regset (dev, GRUB_ATA_REG_LBALOW, sector & 0xFF); + grub_ata_regset (dev, GRUB_ATA_REG_LBAMID, (sector >> 8) & 0xFF); + grub_ata_regset (dev, GRUB_ATA_REG_LBAHIGH, (sector >> 16) & 0xFF); +} + +static grub_err_t +grub_ata_setaddress (struct grub_ata_device *dev, + grub_ata_addressing_t addressing, + grub_disk_addr_t sector, + grub_size_t size) +{ + switch (addressing) + { + case GRUB_ATA_CHS: + { + unsigned int cylinder; + unsigned int head; + unsigned int sect; + + /* Calculate the sector, cylinder and head to use. */ + sect = ((grub_uint32_t) sector % dev->sectors_per_track) + 1; + cylinder = (((grub_uint32_t) sector / dev->sectors_per_track) + / dev->heads); + head = ((grub_uint32_t) sector / dev->sectors_per_track) % dev->heads; + + if (sect > dev->sectors_per_track + || cylinder > dev->cylinders + || head > dev->heads) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + "sector %d can not be addressed " + "using CHS addressing", sector); + + grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head); + if (grub_ata_check_ready (dev)) + return grub_errno; + + grub_ata_regset (dev, GRUB_ATA_REG_SECTNUM, sect); + grub_ata_regset (dev, GRUB_ATA_REG_CYLLSB, cylinder & 0xFF); + grub_ata_regset (dev, GRUB_ATA_REG_CYLMSB, cylinder >> 8); + + break; + } + + case GRUB_ATA_LBA: + if (size == 256) + size = 0; + grub_ata_regset (dev, GRUB_ATA_REG_DISK, + 0xE0 | (dev->device << 4) | ((sector >> 24) & 0x0F)); + if (grub_ata_check_ready (dev)) + return grub_errno; + + grub_ata_setlba (dev, sector, size); + break; + + case GRUB_ATA_LBA48: + if (size == 65536) + size = 0; + + grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | (dev->device << 4)); + if (grub_ata_check_ready (dev)) + return grub_errno; + + /* Set "Previous". */ + grub_ata_setlba (dev, sector >> 24, size >> 8); + /* Set "Current". */ + grub_ata_setlba (dev, sector, size); + + break; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf, int rw) +{ + struct grub_ata_device *dev = (struct grub_ata_device *) disk->data; + + grub_dprintf("ata", "grub_ata_readwrite (size=%u, rw=%d)\n", size, rw); + + grub_ata_addressing_t addressing = dev->addr; + grub_size_t batch; + int cmd, cmd_write; + + if (addressing == GRUB_ATA_LBA48 && ((sector + size) >> 28) != 0) + { + batch = 65536; + cmd = GRUB_ATA_CMD_READ_SECTORS_EXT; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS_EXT; + } + else + { + if (addressing == GRUB_ATA_LBA48) + addressing = GRUB_ATA_LBA; + batch = 256; + cmd = GRUB_ATA_CMD_READ_SECTORS; + cmd_write = GRUB_ATA_CMD_WRITE_SECTORS; + } + + grub_size_t nsectors = 0; + while (nsectors < size) + { + if (size - nsectors < batch) + batch = size - nsectors; + + grub_dprintf("ata", "rw=%d, sector=%llu, batch=%u\n", rw, sector, batch); + + /* Send read/write commmand. */ + if (grub_ata_setaddress (dev, addressing, sector, batch)) + return grub_errno; + + grub_ata_regset (dev, GRUB_ATA_REG_CMD, (! rw ? cmd : cmd_write)); + + unsigned sect; + for (sect = 0; sect < batch; sect++) + { + /* Wait for !BSY, DRQ. */ + if (grub_ata_wait_drq (dev, rw, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + /* Transfer data. */ + if (! rw) + grub_ata_pio_read (dev, buf, GRUB_DISK_SECTOR_SIZE); + else + grub_ata_pio_write (dev, buf, GRUB_DISK_SECTOR_SIZE); + + buf += GRUB_DISK_SECTOR_SIZE; + } + + if (rw) + { + /* Check for write error. */ + if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) + & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error"); + } + + sector += batch; + nsectors += batch; + } + + return GRUB_ERR_NONE; +} + + + +static int +grub_ata_iterate (int (*hook) (const char *name)) +{ + struct grub_ata_device *dev; + + for (dev = grub_ata_devices; dev; dev = dev->next) + { + char devname[5]; + grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + + if (dev->atapi) + continue; + + if (hook (devname)) + return 1; + } + + return 0; +} + +static grub_err_t +grub_ata_open (const char *name, grub_disk_t disk) +{ + struct grub_ata_device *dev; + + for (dev = grub_ata_devices; dev; dev = dev->next) + { + char devname[5]; + grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + if (grub_strcmp (name, devname) == 0) + break; + } + + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + + if (dev->atapi) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); + + disk->total_sectors = dev->size; + + disk->id = (unsigned long) dev; + + disk->has_partitions = 1; + disk->data = dev; + + return 0; +} + +static void +grub_ata_close (grub_disk_t disk __attribute__((unused))) +{ + +} + +static grub_err_t +grub_ata_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + return grub_ata_readwrite (disk, sector, size, buf, 0); +} + +static grub_err_t +grub_ata_write (grub_disk_t disk, + grub_disk_addr_t sector, + grub_size_t size, + const char *buf) +{ + return grub_ata_readwrite (disk, sector, size, (char *) buf, 1); +} + +static struct grub_disk_dev grub_atadisk_dev = + { + .name = "ATA", + .id = GRUB_DISK_DEVICE_ATA_ID, + .iterate = grub_ata_iterate, + .open = grub_ata_open, + .close = grub_ata_close, + .read = grub_ata_read, + .write = grub_ata_write, + .next = 0 + }; + + + +/* ATAPI code. */ + +static int +grub_atapi_iterate (int (*hook) (const char *name, int luns)) +{ + struct grub_ata_device *dev; + + for (dev = grub_ata_devices; dev; dev = dev->next) + { + char devname[7]; + grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + + if (! dev->atapi) + continue; + + if (hook (devname, 1)) + return 1; + } + + return 0; + +} + +static grub_err_t +grub_atapi_read (struct grub_scsi *scsi, + grub_size_t cmdsize __attribute__((unused)), + char *cmd, grub_size_t size, char *buf) +{ + struct grub_ata_device *dev = (struct grub_ata_device *) scsi->data; + + grub_dprintf("ata", "grub_atapi_read (size=%u)\n", size); + + if (grub_atapi_packet (dev, cmd, size)) + return grub_errno; + + grub_size_t nread = 0; + while (nread < size) + { + /* Wait for !BSY, DRQ, I/O, !C/D. */ + if (grub_atapi_wait_drq (dev, GRUB_ATAPI_IREASON_DATA_IN, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + /* Get byte count for this DRQ assertion. */ + unsigned cnt = grub_ata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8 + | grub_ata_regget (dev, GRUB_ATAPI_REG_CNTLOW); + grub_dprintf("ata", "DRQ count=%u\n", cnt); + + /* Count of last transfer may be uneven. */ + if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread))) + return grub_error (GRUB_ERR_READ_ERROR, "Invalid ATAPI transfer count"); + + /* Read the data. */ + grub_ata_pio_read (dev, buf + nread, cnt); + + if (cnt & 1) + buf[nread + cnt - 1] = (char) grub_le_to_cpu16 (grub_inw (dev->ioaddress + GRUB_ATA_REG_DATA)); + + nread += cnt; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)), + grub_size_t cmdsize __attribute__((unused)), + char *cmd __attribute__((unused)), + grub_size_t size __attribute__((unused)), + char *buf __attribute__((unused))) +{ + // XXX: scsi.mod does not use write yet. + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented"); +} + +static grub_err_t +grub_atapi_open (const char *name, struct grub_scsi *scsi) +{ + struct grub_ata_device *dev; + struct grub_ata_device *devfnd = 0; + + for (dev = grub_ata_devices; dev; dev = dev->next) + { + char devname[7]; + grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + + if (!grub_strcmp (devname, name)) + { + devfnd = dev; + break; + } + } + + grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name); + + if (! devfnd) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such ATAPI device"); + + scsi->data = devfnd; + + return GRUB_ERR_NONE; +} + +static void +grub_atapi_close (struct grub_scsi *scsi) +{ + grub_free (scsi->name); +} + +static struct grub_scsi_dev grub_atapi_dev = + { + .name = "ATAPI", + .iterate = grub_atapi_iterate, + .open = grub_atapi_open, + .close = grub_atapi_close, + .read = grub_atapi_read, + .write = grub_atapi_write + }; + + + +GRUB_MOD_INIT(ata) +{ + (void) mod; /* To stop warning. */ + + /* To prevent two drivers operating on the same disks. */ + grub_disk_firmware_is_tainted = 1; + if (grub_disk_firmware_fini) + { + grub_disk_firmware_fini (); + grub_disk_firmware_fini = NULL; + } + + /* ATA initialization. */ + grub_ata_initialize (); + + grub_disk_dev_register (&grub_atadisk_dev); + + /* ATAPI devices are handled by scsi.mod. */ + grub_scsi_dev_register (&grub_atapi_dev); +} + +GRUB_MOD_FINI(ata) +{ + grub_scsi_dev_unregister (&grub_atapi_dev); + grub_disk_dev_unregister (&grub_atadisk_dev); +} diff --git a/disk/ata_pthru.c b/disk/ata_pthru.c new file mode 100644 index 0000000..cc74eb4 --- /dev/null +++ b/disk/ata_pthru.c @@ -0,0 +1,109 @@ +/* ata_pthru.c - ATA pass through for ata.mod. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + + +/* ATA pass through support, used by hdparm.mod. */ +static grub_err_t +grub_ata_pass_through (grub_disk_t disk, + struct grub_disk_ata_pass_through_parms *parms) +{ + if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID) + return grub_error (GRUB_ERR_BAD_DEVICE, + "Device not accessed via ata.mod"); + + struct grub_ata_device *dev = (struct grub_ata_device *) disk->data; + + if (! (parms->size == 0 || parms->size == GRUB_DISK_SECTOR_SIZE)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ATA multi-sector read and DATA OUT not implemented"); + + grub_dprintf ("ata", "ata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n", + parms->taskfile[GRUB_ATA_REG_CMD], + parms->taskfile[GRUB_ATA_REG_FEATURES], + parms->taskfile[GRUB_ATA_REG_SECTORS]); + grub_dprintf ("ata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%d\n", + parms->taskfile[GRUB_ATA_REG_LBAHIGH], + parms->taskfile[GRUB_ATA_REG_LBAMID], + parms->taskfile[GRUB_ATA_REG_LBALOW], parms->size); + + /* Set registers. */ + grub_ata_regset (dev, GRUB_ATA_REG_DISK, 0xE0 | dev->device << 4 + | (parms->taskfile[GRUB_ATA_REG_DISK] & 0xf)); + if (grub_ata_check_ready (dev)) + return grub_errno; + + int i; + for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++) + grub_ata_regset (dev, i, parms->taskfile[i]); + + /* Start command. */ + grub_ata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile[GRUB_ATA_REG_CMD]); + + /* Wait for !BSY. */ + if (grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA)) + return grub_errno; + + /* Check status. */ + grub_int8_t sts = grub_ata_regget (dev, GRUB_ATA_REG_STATUS); + grub_dprintf ("ata", "status=0x%x\n", sts); + + /* Transfer data. */ + if ((sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) == GRUB_ATA_STATUS_DRQ) + { + if (parms->size != GRUB_DISK_SECTOR_SIZE) + return grub_error (GRUB_ERR_READ_ERROR, "DRQ unexpected"); + grub_ata_pio_read (dev, parms->buffer, GRUB_DISK_SECTOR_SIZE); + } + + /* Return registers. */ + for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++) + parms->taskfile[i] = grub_ata_regget (dev, i); + + grub_dprintf ("ata", "status=0x%x, error=0x%x, sectors=0x%x\n", + parms->taskfile[GRUB_ATA_REG_STATUS], + parms->taskfile[GRUB_ATA_REG_ERROR], + parms->taskfile[GRUB_ATA_REG_SECTORS]); + + if (parms->taskfile[GRUB_ATA_REG_STATUS] + & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR)) + return grub_error (GRUB_ERR_READ_ERROR, "ATA passthrough failed"); + + return GRUB_ERR_NONE; +} + + + +GRUB_MOD_INIT(ata_pthru) +{ + (void) mod; + + /* Register ATA pass through function. */ + grub_disk_ata_pass_through = grub_ata_pass_through; +} + +GRUB_MOD_FINI(ata_pthru) +{ + if (grub_disk_ata_pass_through == grub_ata_pass_through) + grub_disk_ata_pass_through = NULL; +} diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c new file mode 100644 index 0000000..ee43bef --- /dev/null +++ b/disk/dmraid_nvidia.c @@ -0,0 +1,165 @@ +/* dmraid_nvidia.c - module to handle Nvidia fakeraid. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define NV_SIGNATURES 4 + +#define NV_IDLE 0 +#define NV_SCDB_INIT_RAID 2 +#define NV_SCDB_REBUILD_RAID 3 +#define NV_SCDB_UPGRADE_RAID 4 +#define NV_SCDB_SYNC_RAID 5 + +#define NV_LEVEL_UNKNOWN 0x00 +#define NV_LEVEL_JBOD 0xFF +#define NV_LEVEL_0 0x80 +#define NV_LEVEL_1 0x81 +#define NV_LEVEL_3 0x83 +#define NV_LEVEL_5 0x85 +#define NV_LEVEL_10 0x8a +#define NV_LEVEL_1_0 0x8180 + +#define NV_ARRAY_FLAG_BOOT 1 /* BIOS use only. */ +#define NV_ARRAY_FLAG_ERROR 2 /* Degraded or offling. */ +#define NV_ARRAY_FLAG_PARITY_VALID 4 /* RAID-3/5 parity valid. */ + +struct grub_nv_array +{ + grub_uint32_t version; + grub_uint32_t signature[NV_SIGNATURES]; + grub_uint8_t raid_job_code; + grub_uint8_t stripe_width; + grub_uint8_t total_volumes; + grub_uint8_t original_width; + grub_uint32_t raid_level; + grub_uint32_t stripe_block_size; + grub_uint32_t stripe_block_size_bytes; + grub_uint32_t stripe_block_size_log2; + grub_uint32_t stripe_mask; + grub_uint32_t stripe_size; + grub_uint32_t stripe_size_bytes; + grub_uint32_t raid_job_mask; + grub_uint32_t original_capacity; + grub_uint32_t flags; +}; + +#define NV_ID_LEN 8 +#define NV_ID_STRING "NVIDIA" +#define NV_VERSION 100 + +#define NV_PRODID_LEN 16 +#define NV_PRODREV_LEN 4 + +struct grub_nv_super +{ + char vendor[NV_ID_LEN]; /* 0x00 - 0x07 ID string. */ + grub_uint32_t size; /* 0x08 - 0x0B Size of metadata in dwords. */ + grub_uint32_t chksum; /* 0x0C - 0x0F Checksum of this struct. */ + grub_uint16_t version; /* 0x10 - 0x11 NV version. */ + grub_uint8_t unit_number; /* 0x12 Disk index in array. */ + grub_uint8_t reserved; /* 0x13. */ + grub_uint32_t capacity; /* 0x14 - 0x17 Array capacity in sectors. */ + grub_uint32_t sector_size; /* 0x18 - 0x1B Sector size. */ + char prodid[NV_PRODID_LEN]; /* 0x1C - 0x2B Array product ID. */ + char prodrev[NV_PRODREV_LEN]; /* 0x2C - 0x2F Array product revision */ + grub_uint32_t unit_flags; /* 0x30 - 0x33 Flags for this disk */ + struct grub_nv_array array; /* Array information */ +} __attribute__ ((packed)); + +static grub_err_t +grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) +{ + grub_disk_addr_t sector; + struct grub_nv_super sb; + + if (disk->partition) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition"); + + sector = grub_disk_get_size (disk) - 2; + + if (grub_disk_read (disk, sector, 0, sizeof (sb), (char *) &sb)) + return grub_errno; + + if (grub_memcmp (sb.vendor, NV_ID_STRING, 6)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); + + if (sb.version != NV_VERSION) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unknown version: %d.%d", sb.version); + + switch (sb.array.raid_level) + { + case NV_LEVEL_0: + array->level = 0; + array->disk_size = sb.capacity / sb.array.total_volumes; + break; + + case NV_LEVEL_1: + array->level = 1; + array->disk_size = sb.capacity; + break; + + case NV_LEVEL_5: + array->level = 5; + array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC; + array->disk_size = sb.capacity / (sb.array.total_volumes - 1); + break; + + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID level: %d", sb.array.raid_level); + } + + array->number = 0; + array->total_devs = sb.array.total_volumes; + array->chunk_size = sb.array.stripe_block_size; + array->index = sb.unit_number; + array->uuid_len = sizeof (sb.array.signature); + array->uuid = grub_malloc (sizeof (sb.array.signature)); + if (! array->uuid) + return grub_errno; + + grub_memcpy (array->uuid, (char *) &sb.array.signature, + sizeof (sb.array.signature)); + + return 0; +} + +static struct grub_raid grub_dmraid_nv_dev = +{ + .name = "dmraid_nv", + .detect = grub_dmraid_nv_detect, + .next = 0 +}; + +GRUB_MOD_INIT(dm_nv) +{ + grub_raid_register (&grub_dmraid_nv_dev); +} + +GRUB_MOD_FINI(dm_nv) +{ + grub_raid_register (&grub_dmraid_nv_dev); +} diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c new file mode 100644 index 0000000..767ebf8 --- /dev/null +++ b/disk/efi/efidisk.c @@ -0,0 +1,859 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_efidisk_data +{ + grub_efi_handle_t handle; + grub_efi_device_path_t *device_path; + grub_efi_device_path_t *last_device_path; + grub_efi_block_io_t *block_io; + grub_efi_disk_io_t *disk_io; + struct grub_efidisk_data *next; +}; + +/* GUIDs. */ +static grub_efi_guid_t disk_io_guid = GRUB_EFI_DISK_IO_GUID; +static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_GUID; + +static struct grub_efidisk_data *fd_devices; +static struct grub_efidisk_data *hd_devices; +static struct grub_efidisk_data *cd_devices; + +/* Duplicate a device path. */ +static grub_efi_device_path_t * +duplicate_device_path (const grub_efi_device_path_t *dp) +{ + grub_efi_device_path_t *p; + grub_size_t total_size = 0; + + for (p = (grub_efi_device_path_t *) dp; + ; + p = GRUB_EFI_NEXT_DEVICE_PATH (p)) + { + total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p); + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) + break; + } + + p = grub_malloc (total_size); + if (! p) + return 0; + + grub_memcpy (p, dp, total_size); + return p; +} + +/* Return the device path node right before the end node. */ +static grub_efi_device_path_t * +find_last_device_path (const grub_efi_device_path_t *dp) +{ + grub_efi_device_path_t *next, *p; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + return 0; + + for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p); + ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next); + p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next)) + ; + + return p; +} + +/* Compare device paths. */ +static int +compare_device_paths (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2) +{ + if (! dp1 || ! dp2) + /* Return non-zero. */ + return 1; + + while (1) + { + grub_efi_uint8_t type1, type2; + grub_efi_uint8_t subtype1, subtype2; + grub_efi_uint16_t len1, len2; + int ret; + + type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1); + type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2); + + if (type1 != type2) + return (int) type2 - (int) type1; + + subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1); + subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2); + + if (subtype1 != subtype2) + return (int) subtype1 - (int) subtype2; + + len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1); + len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2); + + if (len1 != len2) + return (int) len1 - (int) len2; + + ret = grub_memcmp (dp1, dp2, len1); + if (ret != 0) + return ret; + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1)) + break; + + dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1); + dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2); + } + + return 0; +} + +static struct grub_efidisk_data * +make_devices (void) +{ + grub_efi_uintn_t num_handles; + grub_efi_handle_t *handles; + grub_efi_handle_t *handle; + struct grub_efidisk_data *devices = 0; + + /* Find handles which support the disk io interface. */ + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid, + 0, &num_handles); + if (! handles) + return 0; + + /* Make a linked list of devices. */ + for (handle = handles; num_handles--; handle++) + { + grub_efi_device_path_t *dp; + grub_efi_device_path_t *ldp; + struct grub_efidisk_data *d; + grub_efi_block_io_t *bio; + grub_efi_disk_io_t *dio; + + dp = grub_efi_get_device_path (*handle); + if (! dp) + continue; + + ldp = find_last_device_path (dp); + if (! ldp) + /* This is empty. Why? */ + continue; + + bio = grub_efi_open_protocol (*handle, &block_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + dio = grub_efi_open_protocol (*handle, &disk_io_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (! bio || ! dio) + /* This should not happen... Why? */ + continue; + + d = grub_malloc (sizeof (*d)); + if (! d) + { + /* Uggh. */ + grub_free (handles); + return 0; + } + + d->handle = *handle; + d->device_path = dp; + d->last_device_path = ldp; + d->block_io = bio; + d->disk_io = dio; + d->next = devices; + devices = d; + } + + grub_free (handles); + + return devices; +} + +/* Find the parent device. */ +static struct grub_efidisk_data * +find_parent_device (struct grub_efidisk_data *devices, + struct grub_efidisk_data *d) +{ + grub_efi_device_path_t *dp, *ldp; + struct grub_efidisk_data *parent; + + dp = duplicate_device_path (d->device_path); + if (! dp) + return 0; + + ldp = find_last_device_path (dp); + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length[0] = sizeof (*ldp); + ldp->length[1] = 0; + + for (parent = devices; parent; parent = parent->next) + { + /* Ignore itself. */ + if (parent == d) + continue; + + if (compare_device_paths (parent->device_path, dp) == 0) + { + /* Found. */ + if (! parent->last_device_path) + parent = 0; + + break; + } + } + + grub_free (dp); + return parent; +} + +static int +iterate_child_devices (struct grub_efidisk_data *devices, + struct grub_efidisk_data *d, + int (*hook) (struct grub_efidisk_data *child)) +{ + struct grub_efidisk_data *p; + + for (p = devices; p; p = p->next) + { + grub_efi_device_path_t *dp, *ldp; + + dp = duplicate_device_path (p->device_path); + if (! dp) + return 0; + + ldp = find_last_device_path (dp); + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length[0] = sizeof (*ldp); + ldp->length[1] = 0; + + if (compare_device_paths (dp, d->device_path) == 0) + if (hook (p)) + { + grub_free (dp); + return 1; + } + + grub_free (dp); + } + + return 0; +} + +/* Add a device into a list of devices in an ascending order. */ +static void +add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d) +{ + struct grub_efidisk_data **p; + struct grub_efidisk_data *n; + + for (p = devices; *p; p = &((*p)->next)) + { + int ret; + + ret = compare_device_paths (find_last_device_path ((*p)->device_path), + find_last_device_path (d->device_path)); + if (ret == 0) + ret = compare_device_paths ((*p)->device_path, + d->device_path); + if (ret == 0) + return; + else if (ret > 0) + break; + } + + n = grub_malloc (sizeof (*n)); + if (! n) + return; + + grub_memcpy (n, d, sizeof (*n)); + n->next = (*p); + (*p) = n; +} + +/* Name the devices. */ +static void +name_devices (struct grub_efidisk_data *devices) +{ + struct grub_efidisk_data *d; + + /* First, identify devices by media device paths. */ + for (d = devices; d; d = d->next) + { + grub_efi_device_path_t *dp; + + dp = d->last_device_path; + if (! dp) + continue; + + if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) + { + int is_hard_drive = 0; + + switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp)) + { + case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: + is_hard_drive = 1; + /* Fall through by intention. */ + case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: + { + struct grub_efidisk_data *parent; + + parent = find_parent_device (devices, d); + if (parent) + { + if (is_hard_drive) + { +#if 0 + grub_printf ("adding a hard drive by a partition: "); + grub_print_device_path (parent->device_path); +#endif + add_device (&hd_devices, parent); + } + else + { +#if 0 + grub_printf ("adding a cdrom by a partition: "); + grub_print_device_path (parent->device_path); +#endif + add_device (&cd_devices, parent); + } + + /* Mark the parent as used. */ + parent->last_device_path = 0; + } + } + /* Mark itself as used. */ + d->last_device_path = 0; + break; + + default: + /* For now, ignore the others. */ + break; + } + } + } + + /* Let's see what can be added more. */ + for (d = devices; d; d = d->next) + { + grub_efi_device_path_t *dp; + grub_efi_block_io_media_t *m; + + dp = d->last_device_path; + if (! dp) + continue; + + m = d->block_io->media; + if (m->logical_partition) + { + /* Only one partition in a non-media device. Assume that this + is a floppy drive. */ +#if 0 + grub_printf ("adding a floppy by guessing: "); + grub_print_device_path (d->device_path); +#endif + add_device (&fd_devices, d); + } + else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE) + { + /* This check is too heuristic, but assume that this is a + CDROM drive. */ +#if 0 + grub_printf ("adding a cdrom by guessing: "); + grub_print_device_path (d->device_path); +#endif + add_device (&cd_devices, d); + } + else + { + /* The default is a hard drive. */ +#if 0 + grub_printf ("adding a hard drive by guessing: "); + grub_print_device_path (d->device_path); +#endif + add_device (&hd_devices, d); + } + } +} + +static void +free_devices (struct grub_efidisk_data *devices) +{ + struct grub_efidisk_data *p, *q; + + for (p = devices; p; p = q) + { + q = p->next; + grub_free (p); + } +} + +/* Enumerate all disks to name devices. */ +static void +enumerate_disks (void) +{ + struct grub_efidisk_data *devices; + + devices = make_devices (); + if (! devices) + return; + + name_devices (devices); + free_devices (devices); +} + +static int +grub_efidisk_iterate (int (*hook) (const char *name)) +{ + struct grub_efidisk_data *d; + char buf[16]; + int count; + + for (d = fd_devices, count = 0; d; d = d->next, count++) + { + grub_sprintf (buf, "fd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); + if (hook (buf)) + return 1; + } + + for (d = hd_devices, count = 0; d; d = d->next, count++) + { + grub_sprintf (buf, "hd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); + if (hook (buf)) + return 1; + } + + for (d = cd_devices, count = 0; d; d = d->next, count++) + { + grub_sprintf (buf, "cd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); + if (hook (buf)) + return 1; + } + + return 0; +} + +static int +get_drive_number (const char *name) +{ + unsigned long drive; + + if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd') + goto fail; + + drive = grub_strtoul (name + 2, 0, 10); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + + return (int) drive ; + + fail: + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a efidisk"); + return -1; +} + +static struct grub_efidisk_data * +get_device (struct grub_efidisk_data *devices, int num) +{ + struct grub_efidisk_data *d; + + for (d = devices; d && num; d = d->next, num--) + ; + + if (num == 0) + return d; + + return 0; +} + +static grub_err_t +grub_efidisk_open (const char *name, struct grub_disk *disk) +{ + int num; + struct grub_efidisk_data *d = 0; + grub_efi_block_io_media_t *m; + + grub_dprintf ("efidisk", "opening %s\n", name); + + num = get_drive_number (name); + if (num < 0) + return grub_errno; + + switch (name[0]) + { + case 'f': + disk->has_partitions = 0; + d = get_device (fd_devices, num); + break; + case 'c': + /* FIXME: a CDROM should have partitions, but not implemented yet. */ + disk->has_partitions = 0; + d = get_device (cd_devices, num); + break; + case 'h': + disk->has_partitions = 1; + d = get_device (hd_devices, num); + break; + default: + /* Never reach here. */ + break; + } + + if (! d) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + + disk->id = ((num << 8) | name[0]); + m = d->block_io->media; + /* FIXME: Probably it is better to store the block size in the disk, + and total sectors should be replaced with total blocks. */ + grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n", + m, (unsigned long long) m->last_block, m->block_size); + disk->total_sectors = (m->last_block + * (m->block_size >> GRUB_DISK_SECTOR_BITS)); + disk->data = d; + + grub_dprintf ("efidisk", "opening %s succeeded\n", name); + + return GRUB_ERR_NONE; +} + +static void +grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused))) +{ + /* EFI disks do not allocate extra memory, so nothing to do here. */ + grub_dprintf ("efidisk", "closing %s\n", disk->name); +} + +static grub_err_t +grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + /* For now, use the disk io interface rather than the block io's. */ + struct grub_efidisk_data *d; + grub_efi_disk_io_t *dio; + grub_efi_block_io_t *bio; + grub_efi_status_t status; + + d = disk->data; + dio = d->disk_io; + bio = d->block_io; + + grub_dprintf ("efidisk", + "reading 0x%lx sectors at the sector 0x%llx from %s\n", + (unsigned long) size, (unsigned long long) sector, disk->name); + + status = efi_call_5 (dio->read, dio, bio->media->media_id, + (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS, + (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS, + buf); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error"); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + /* For now, use the disk io interface rather than the block io's. */ + struct grub_efidisk_data *d; + grub_efi_disk_io_t *dio; + grub_efi_block_io_t *bio; + grub_efi_status_t status; + + d = disk->data; + dio = d->disk_io; + bio = d->block_io; + + grub_dprintf ("efidisk", + "writing 0x%lx sectors at the sector 0x%llx to %s\n", + (unsigned long) size, (unsigned long long) sector, disk->name); + + status = efi_call_5 (dio->write, dio, bio->media->media_id, + (grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS, + (grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS, + (void *) buf); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error"); + + return GRUB_ERR_NONE; +} + +static struct grub_disk_dev grub_efidisk_dev = + { + .name = "efidisk", + .id = GRUB_DISK_DEVICE_EFIDISK_ID, + .iterate = grub_efidisk_iterate, + .open = grub_efidisk_open, + .close = grub_efidisk_close, + .read = grub_efidisk_read, + .write = grub_efidisk_write, + .next = 0 + }; + +void +grub_efidisk_init (void) +{ + enumerate_disks (); + grub_disk_dev_register (&grub_efidisk_dev); +} + +void +grub_efidisk_fini (void) +{ + free_devices (fd_devices); + free_devices (hd_devices); + free_devices (cd_devices); + grub_disk_dev_unregister (&grub_efidisk_dev); +} + +/* Some utility functions to map GRUB devices with EFI devices. */ +grub_efi_handle_t +grub_efidisk_get_device_handle (grub_disk_t disk) +{ + struct grub_efidisk_data *d; + char type; + + if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID) + return 0; + + d = disk->data; + type = disk->name[0]; + + switch (type) + { + case 'f': + /* This is the simplest case. */ + return d->handle; + + case 'c': + /* FIXME: probably this is not correct. */ + return d->handle; + + case 'h': + /* If this is the whole disk, just return its own data. */ + if (! disk->partition) + return d->handle; + + /* Otherwise, we must query the corresponding device to the firmware. */ + { + struct grub_efidisk_data *devices; + grub_efi_handle_t handle = 0; + auto int find_partition (struct grub_efidisk_data *c); + + int find_partition (struct grub_efidisk_data *c) + { + grub_efi_hard_drive_device_path_t hd; + + grub_memcpy (&hd, c->last_device_path, sizeof (hd)); + + if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path) + == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path) + == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE) + && (grub_partition_get_start (disk->partition) + == hd.partition_start) + && (grub_partition_get_len (disk->partition) + == hd.partition_size)) + { + handle = c->handle; + return 1; + } + + return 0; + } + + devices = make_devices (); + iterate_child_devices (devices, d, find_partition); + free_devices (devices); + + if (handle != 0) + return handle; + } + break; + + default: + break; + } + + return 0; +} + +char * +grub_efidisk_get_device_name (grub_efi_handle_t *handle) +{ + grub_efi_device_path_t *dp, *ldp; + + dp = grub_efi_get_device_path (handle); + if (! dp) + return 0; + + ldp = find_last_device_path (dp); + if (! ldp) + return 0; + + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) + == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) + { + /* This is a hard disk partition. */ + grub_disk_t parent = 0; + char *partition_name = 0; + char *device_name; + grub_efi_device_path_t *dup_dp, *dup_ldp; + grub_efi_hard_drive_device_path_t hd; + auto int find_parent_disk (const char *name); + auto int find_partition (grub_disk_t disk, const grub_partition_t part); + + /* Find the disk which is the parent of a given hard disk partition. */ + int find_parent_disk (const char *name) + { + grub_disk_t disk; + + disk = grub_disk_open (name); + if (! disk) + return 1; + + if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID) + { + struct grub_efidisk_data *d; + + d = disk->data; + if (compare_device_paths (d->device_path, dup_dp) == 0) + { + parent = disk; + return 1; + } + } + + grub_disk_close (disk); + return 0; + } + + /* Find the identical partition. */ + int find_partition (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t part) + { + if (grub_partition_get_start (part) == hd.partition_start + && grub_partition_get_len (part) == hd.partition_size) + { + partition_name = grub_partition_get_name (part); + return 1; + } + + return 0; + } + + /* It is necessary to duplicate the device path so that GRUB + can overwrite it. */ + dup_dp = duplicate_device_path (dp); + if (! dup_dp) + return 0; + + dup_ldp = find_last_device_path (dup_dp); + dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + dup_ldp->length[0] = sizeof (*dup_ldp); + dup_ldp->length[1] = 0; + + grub_efidisk_iterate (find_parent_disk); + grub_free (dup_dp); + + if (! parent) + return 0; + + /* Find a partition which matches the hard drive device path. */ + grub_memcpy (&hd, ldp, sizeof (hd)); + grub_partition_iterate (parent, find_partition); + + if (! partition_name) + { + grub_disk_close (parent); + return 0; + } + + device_name = grub_malloc (grub_strlen (parent->name) + 1 + + grub_strlen (partition_name) + 1); + if (! device_name) + { + grub_free (partition_name); + grub_disk_close (parent); + return 0; + } + + grub_sprintf (device_name, "%s,%s", parent->name, partition_name); + grub_free (partition_name); + grub_disk_close (parent); + return device_name; + } + else + { + /* This should be an entire disk. */ + auto int find_disk (const char *name); + char *device_name = 0; + + int find_disk (const char *name) + { + grub_disk_t disk; + + disk = grub_disk_open (name); + if (! disk) + return 1; + + if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID) + { + struct grub_efidisk_data *d; + + d = disk->data; + if (compare_device_paths (d->device_path, dp) == 0) + { + device_name = grub_strdup (disk->name); + grub_disk_close (disk); + return 1; + } + } + + grub_disk_close (disk); + return 0; + + } + + grub_efidisk_iterate (find_disk); + return device_name; + } + + return 0; +} diff --git a/disk/fs_uuid.c b/disk/fs_uuid.c new file mode 100644 index 0000000..125d29b --- /dev/null +++ b/disk/fs_uuid.c @@ -0,0 +1,137 @@ +/* fs_uuid.c - Access disks by their filesystem UUID. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +static grub_device_t +search_fs_uuid (const char *key, unsigned long *count) +{ + *count = 0; + grub_device_t ret = NULL; + + auto int iterate_device (const char *name); + int iterate_device (const char *name) + { + grub_device_t dev; + + dev = grub_device_open (name); + if (dev) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + if (fs && fs->uuid) + { + char *uuid; + + (fs->uuid) (dev, &uuid); + if (grub_errno == GRUB_ERR_NONE && uuid) + { + (*count)++; + + if (grub_strcasecmp (uuid, key) == 0) + { + ret = dev; + grub_free (uuid); + return 1; + } + grub_free (uuid); + } + } + + grub_device_close (dev); + } + + grub_errno = GRUB_ERR_NONE; + return 0; + } + + grub_device_iterate (iterate_device); + + return ret; +} + +static grub_err_t +grub_fs_uuid_open (const char *name, grub_disk_t disk) +{ + grub_device_t dev; + + if (grub_strncmp (name, "UUID=", sizeof ("UUID=")-1)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a UUID virtual volume"); + + dev = search_fs_uuid (name + sizeof ("UUID=") - 1, &disk->id); + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching UUID found"); + + disk->total_sectors = dev->disk->total_sectors; + disk->has_partitions = 0; + disk->partition = dev->disk->partition; + disk->data = dev->disk; + + return GRUB_ERR_NONE; +} + +static void +grub_fs_uuid_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_fs_uuid_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_disk_t parent = disk->data; + return parent->dev->read (parent, sector, size, buf); +} + +static grub_err_t +grub_fs_uuid_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + grub_disk_t parent = disk->data; + return parent->dev->write (parent, sector, size, buf); +} + +static struct grub_disk_dev grub_fs_uuid_dev = + { + .name = "fs_uuid", + .id = GRUB_DISK_DEVICE_UUID_ID, + .open = grub_fs_uuid_open, + .close = grub_fs_uuid_close, + .read = grub_fs_uuid_read, + .write = grub_fs_uuid_write, + .next = 0 + }; + +GRUB_MOD_INIT(fs_uuid) +{ + grub_disk_dev_register (&grub_fs_uuid_dev); +} + +GRUB_MOD_FINI(fs_uuid) +{ + grub_disk_dev_unregister (&grub_fs_uuid_dev); +} diff --git a/disk/host.c b/disk/host.c new file mode 100644 index 0000000..bb8828a --- /dev/null +++ b/disk/host.c @@ -0,0 +1,97 @@ +/* host.c - Dummy disk driver to provide access to the hosts filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* When using the disk, make a reference to this module. Otherwise + the user will end up with a useless module :-). */ + +#include +#include +#include + +int grub_disk_host_i_want_a_reference; + +static int +grub_host_iterate (int (*hook) (const char *name)) +{ + if (hook ("host")) + return 1; + return 0; +} + +static grub_err_t +grub_host_open (const char *name, grub_disk_t disk) +{ + if (grub_strcmp (name, "host")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a host disk"); + + disk->total_sectors = 0; + disk->id = (unsigned long) "host"; + + disk->has_partitions = 0; + disk->data = 0; + + return GRUB_ERR_NONE; +} + +static void +grub_host_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_host_read (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + char *buf __attribute((unused))) +{ + return GRUB_ERR_OUT_OF_RANGE; +} + +static grub_err_t +grub_host_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_OUT_OF_RANGE; +} + +static struct grub_disk_dev grub_host_dev = + { + /* The only important line in this file :-) */ + .name = "host", + .id = GRUB_DISK_DEVICE_HOST_ID, + .iterate = grub_host_iterate, + .open = grub_host_open, + .close = grub_host_close, + .read = grub_host_read, + .write = grub_host_write, + .next = 0 + }; + +GRUB_MOD_INIT(host) +{ + (void) mod; /* To stop warning. */ + grub_disk_dev_register (&grub_host_dev); +} + +GRUB_MOD_FINI(host) +{ + grub_disk_dev_unregister (&grub_host_dev); +} diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c new file mode 100644 index 0000000..120d46f --- /dev/null +++ b/disk/i386/pc/biosdisk.c @@ -0,0 +1,390 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int cd_drive = 0; + +static int +grub_biosdisk_get_drive (const char *name) +{ + unsigned long drive; + + if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') + goto fail; + + drive = grub_strtoul (name + 2, 0, 10); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + + if (name[0] == 'h') + drive += 0x80; + + return (int) drive ; + + fail: + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a biosdisk"); + return -1; +} + +static int +grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) +{ + char name[10]; + + grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); + return hook (name); +} + +static int +grub_biosdisk_iterate (int (*hook) (const char *name)) +{ + int drive; + int num_floppies; + + /* For hard disks, attempt to read the MBR. */ + for (drive = 0x80; drive < 0x90; drive++) + { + if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, + GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) + { + grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); + break; + } + + if (grub_biosdisk_call_hook (hook, drive)) + return 1; + } + + if (cd_drive) + { + if (grub_biosdisk_call_hook (hook, cd_drive)) + return 1; + } + + /* For floppy disks, we can get the number safely. */ + num_floppies = grub_biosdisk_get_num_floppies (); + for (drive = 0; drive < num_floppies; drive++) + if (grub_biosdisk_call_hook (hook, drive)) + return 1; + + return 0; +} + +static grub_err_t +grub_biosdisk_open (const char *name, grub_disk_t disk) +{ + grub_uint64_t total_sectors = 0; + int drive; + struct grub_biosdisk_data *data; + + drive = grub_biosdisk_get_drive (name); + if (drive < 0) + return grub_errno; + + disk->has_partitions = ((drive & 0x80) && (drive != cd_drive)); + disk->id = drive; + + data = (struct grub_biosdisk_data *) grub_malloc (sizeof (*data)); + if (! data) + return grub_errno; + + data->drive = drive; + data->flags = 0; + + if ((cd_drive) && (drive == cd_drive)) + { + data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; + data->sectors = 32; + total_sectors = ULONG_MAX; /* TODO: get the correct size. */ + } + else if (drive & 0x80) + { + /* HDD */ + int version; + + version = grub_biosdisk_check_int13_extensions (drive); + if (version) + { + struct grub_biosdisk_drp *drp + = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Clear out the DRP. */ + grub_memset (drp, 0, sizeof (*drp)); + drp->size = sizeof (*drp); + if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp)) + { + data->flags = GRUB_BIOSDISK_FLAG_LBA; + + if (drp->total_sectors) + total_sectors = drp->total_sectors; + else + /* Some buggy BIOSes doesn't return the total sectors + correctly but returns zero. So if it is zero, compute + it by C/H/S returned by the LBA BIOS call. */ + total_sectors = drp->cylinders * drp->heads * drp->sectors; + } + } + } + + if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM)) + { + if (grub_biosdisk_get_diskinfo_standard (drive, + &data->cylinders, + &data->heads, + &data->sectors) != 0) + { + grub_free (data); + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get C/H/S values"); + } + + if (! total_sectors) + total_sectors = data->cylinders * data->heads * data->sectors; + } + + disk->total_sectors = total_sectors; + disk->data = data; + + return GRUB_ERR_NONE; +} + +static void +grub_biosdisk_close (grub_disk_t disk) +{ + grub_free (disk->data); +} + +/* For readability. */ +#define GRUB_BIOSDISK_READ 0 +#define GRUB_BIOSDISK_WRITE 1 + +#define GRUB_BIOSDISK_CDROM_RETRY_COUNT 3 + +static grub_err_t +grub_biosdisk_rw (int cmd, grub_disk_t disk, + grub_disk_addr_t sector, grub_size_t size, + unsigned segment) +{ + struct grub_biosdisk_data *data = disk->data; + + if (data->flags & GRUB_BIOSDISK_FLAG_LBA) + { + struct grub_biosdisk_dap *dap; + + dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + + (data->sectors + << GRUB_DISK_SECTOR_BITS)); + dap->length = sizeof (*dap); + dap->reserved = 0; + dap->blocks = size; + dap->buffer = segment << 16; /* The format SEGMENT:ADDRESS. */ + dap->block = sector; + + if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) + { + int i; + + if (cmd) + return grub_error (GRUB_ERR_WRITE_ERROR, "can\'t write to cdrom"); + + dap->blocks = (dap->blocks + 3) >> 2; + dap->block >>= 2; + + for (i = 0; i < GRUB_BIOSDISK_CDROM_RETRY_COUNT; i++) + if (! grub_biosdisk_rw_int13_extensions (0x42, data->drive, dap)) + break; + + if (i == GRUB_BIOSDISK_CDROM_RETRY_COUNT) + return grub_error (GRUB_ERR_READ_ERROR, "cdrom read error"); + } + else + if (grub_biosdisk_rw_int13_extensions (cmd + 0x42, data->drive, dap)) + { + /* Fall back to the CHS mode. */ + data->flags &= ~GRUB_BIOSDISK_FLAG_LBA; + disk->total_sectors = data->cylinders * data->heads * data->sectors; + return grub_biosdisk_rw (cmd, disk, sector, size, segment); + } + } + else + { + unsigned coff, hoff, soff; + unsigned head; + + /* It is impossible to reach over 8064 MiB (a bit less than LBA24) with + the traditional CHS access. */ + if (sector > + 1024 /* cylinders */ * + 256 /* heads */ * + 63 /* spt */) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); + + soff = ((grub_uint32_t) sector) % data->sectors + 1; + head = ((grub_uint32_t) sector) / data->sectors; + hoff = head % data->heads; + coff = head / data->heads; + + if (coff >= data->cylinders) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); + + if (grub_biosdisk_rw_standard (cmd + 0x02, data->drive, + coff, hoff, soff, size, segment)) + { + switch (cmd) + { + case GRUB_BIOSDISK_READ: + return grub_error (GRUB_ERR_READ_ERROR, "biosdisk read error"); + case GRUB_BIOSDISK_WRITE: + return grub_error (GRUB_ERR_WRITE_ERROR, "biosdisk write error"); + } + } + } + + return GRUB_ERR_NONE; +} + +/* Return the number of sectors which can be read safely at a time. */ +static grub_size_t +get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors) +{ + grub_size_t size; + grub_uint32_t offset; + + /* OFFSET = SECTOR % SECTORS */ + grub_divmod64 (sector, sectors, &offset); + + size = sectors - offset; + + /* Limit the max to 0x7f because of Phoenix EDD. */ + if (size > 0x7f) + size = 0x7f; + + return size; +} + +static grub_err_t +grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + struct grub_biosdisk_data *data = disk->data; + + while (size) + { + grub_size_t len; + + len = get_safe_sectors (sector, data->sectors); + if (len > size) + len = size; + + if (grub_biosdisk_rw (GRUB_BIOSDISK_READ, disk, sector, len, + GRUB_MEMORY_MACHINE_SCRATCH_SEG)) + return grub_errno; + + grub_memcpy (buf, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + len << GRUB_DISK_SECTOR_BITS); + buf += len << GRUB_DISK_SECTOR_BITS; + sector += len; + size -= len; + } + + return grub_errno; +} + +static grub_err_t +grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + struct grub_biosdisk_data *data = disk->data; + + while (size) + { + grub_size_t len; + + len = get_safe_sectors (sector, data->sectors); + if (len > size) + len = size; + + grub_memcpy ((void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, buf, + len << GRUB_DISK_SECTOR_BITS); + + if (grub_biosdisk_rw (GRUB_BIOSDISK_WRITE, disk, sector, len, + GRUB_MEMORY_MACHINE_SCRATCH_SEG)) + return grub_errno; + + buf += len << GRUB_DISK_SECTOR_BITS; + sector += len; + size -= len; + } + + return grub_errno; +} + +static struct grub_disk_dev grub_biosdisk_dev = + { + .name = "biosdisk", + .id = GRUB_DISK_DEVICE_BIOSDISK_ID, + .iterate = grub_biosdisk_iterate, + .open = grub_biosdisk_open, + .close = grub_biosdisk_close, + .read = grub_biosdisk_read, + .write = grub_biosdisk_write, + .next = 0 + }; + +static void +grub_disk_biosdisk_fini (void) +{ + grub_disk_dev_unregister (&grub_biosdisk_dev); +} + +GRUB_MOD_INIT(biosdisk) +{ + struct grub_biosdisk_cdrp *cdrp + = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + if (grub_disk_firmware_is_tainted) + { + grub_printf ("Firmware is marked as tainted, refusing to initialize.\n"); + return; + } + grub_disk_firmware_fini = grub_disk_biosdisk_fini; + + grub_memset (cdrp, 0, sizeof (*cdrp)); + cdrp->size = sizeof (*cdrp); + cdrp->media_type = 0xFF; + if ((! grub_biosdisk_get_cdinfo_int13_extensions (grub_boot_drive, cdrp)) && + ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK) + == GRUB_BIOSDISK_CDTYPE_NO_EMUL)) + cd_drive = cdrp->drive_no; + + grub_disk_dev_register (&grub_biosdisk_dev); +} + +GRUB_MOD_FINI(biosdisk) +{ + grub_disk_biosdisk_fini (); +} diff --git a/disk/ieee1275/nand.c b/disk/ieee1275/nand.c new file mode 100644 index 0000000..ba79faa --- /dev/null +++ b/disk/ieee1275/nand.c @@ -0,0 +1,216 @@ +/* nand.c - NAND flash disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +struct grub_nand_data +{ + grub_ieee1275_ihandle_t handle; + grub_uint32_t block_size; +}; + +static int +grub_nand_iterate (int (*hook) (const char *name)) +{ + auto int dev_iterate (struct grub_ieee1275_devalias *alias); + int dev_iterate (struct grub_ieee1275_devalias *alias) + { + if (! grub_strcmp (alias->name, "nand")) + { + hook (alias->name); + return 1; + } + + return 0; + } + + grub_devalias_iterate (dev_iterate); + return 0; +} + +static grub_err_t +grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf); + +static grub_err_t +grub_nand_open (const char *name, grub_disk_t disk) +{ + grub_ieee1275_ihandle_t dev_ihandle = 0; + struct grub_nand_data *data = 0; + struct size_args + { + struct grub_ieee1275_common_hdr common; + char *method; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t result; + grub_ieee1275_cell_t size1; + grub_ieee1275_cell_t size2; + } args; + + if (! grub_strstr (name, "nand")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Not a nand device"); + + data = grub_malloc (sizeof (*data)); + if (! data) + goto fail; + + grub_ieee1275_open (name, &dev_ihandle); + if (! dev_ihandle) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + goto fail; + } + + data->handle = dev_ihandle; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); + args.method = "block-size"; + args.ihandle = dev_ihandle; + args.result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get block size"); + goto fail; + } + + data->block_size = (args.size1 >> GRUB_DISK_SECTOR_BITS); + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); + args.method = "size"; + args.ihandle = dev_ihandle; + args.result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get disk size"); + goto fail; + } + + disk->total_sectors = args.size1; + disk->total_sectors <<= 32; + disk->total_sectors += args.size2; + disk->total_sectors >>= GRUB_DISK_SECTOR_BITS; + + disk->id = dev_ihandle; + + disk->has_partitions = 0; + disk->data = data; + + return 0; + +fail: + if (dev_ihandle) + grub_ieee1275_close (dev_ihandle); + grub_free (data); + return grub_errno; +} + +static void +grub_nand_close (grub_disk_t disk) +{ + grub_ieee1275_close (((struct grub_nand_data *) disk->data)->handle); + grub_free (disk->data); +} + +static grub_err_t +grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + struct grub_nand_data *data = disk->data; + grub_size_t bsize, ofs; + + struct read_args + { + struct grub_ieee1275_common_hdr common; + char *method; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t ofs; + grub_ieee1275_cell_t page; + grub_ieee1275_cell_t len; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t result; + } args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1); + args.method = "pio-read"; + args.ihandle = data->handle; + args.buf = (grub_ieee1275_cell_t) buf; + args.page = (grub_ieee1275_cell_t) ((grub_size_t) sector / data->block_size); + + ofs = ((grub_size_t) sector % data->block_size) << GRUB_DISK_SECTOR_BITS; + size <<= GRUB_DISK_SECTOR_BITS; + bsize = (data->block_size << GRUB_DISK_SECTOR_BITS); + + do + { + grub_size_t len; + + len = (ofs + size > bsize) ? (bsize - ofs) : size; + + args.len = (grub_ieee1275_cell_t) len; + args.ofs = (grub_ieee1275_cell_t) ofs; + args.result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) + return grub_error (GRUB_ERR_READ_ERROR, "Read error"); + + ofs = 0; + size -= len; + args.buf += len; + args.page++; + } while (size); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_nand_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static struct grub_disk_dev grub_nand_dev = + { + .name = "nand", + .id = GRUB_DISK_DEVICE_NAND_ID, + .iterate = grub_nand_iterate, + .open = grub_nand_open, + .close = grub_nand_close, + .read = grub_nand_read, + .write = grub_nand_write, + .next = 0 + }; + +GRUB_MOD_INIT(nand) +{ + grub_disk_dev_register (&grub_nand_dev); +} + +GRUB_MOD_FINI(nand) +{ + grub_disk_dev_unregister (&grub_nand_dev); +} diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c new file mode 100644 index 0000000..fec56be --- /dev/null +++ b/disk/ieee1275/ofdisk.c @@ -0,0 +1,211 @@ +/* ofdisk.c - Open Firmware disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static int +grub_ofdisk_iterate (int (*hook) (const char *name)) +{ + auto int dev_iterate (struct grub_ieee1275_devalias *alias); + + int dev_iterate (struct grub_ieee1275_devalias *alias) + { + grub_dprintf ("disk", "disk name = %s\n", alias->name); + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY)) + { + grub_ieee1275_phandle_t dev; + char tmp[8]; + + if (grub_ieee1275_finddevice (alias->path, &dev)) + { + grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path); + return 0; + } + + if (grub_ieee1275_get_property (dev, "iconname", tmp, + sizeof tmp, 0)) + { + grub_dprintf ("disk", "get iconname failed\n"); + return 0; + } + + if (grub_strcmp (tmp, "sdmmc")) + { + grub_dprintf ("disk", "device is not an SD card\n"); + return 0; + } + } + + if (! grub_strcmp (alias->type, "block")) + hook (alias->name); + else if ((! grub_strcmp (alias->type, "scsi")) + || (! grub_strcmp (alias->type, "ide")) + || (! grub_strcmp (alias->type, "ata"))) + /* Search for block-type children of these bus controllers. */ + grub_children_iterate (alias->name, dev_iterate); + return 0; + } + + grub_devalias_iterate (dev_iterate); + return 0; +} + +static grub_err_t +grub_ofdisk_open (const char *name, grub_disk_t disk) +{ + grub_ieee1275_phandle_t dev; + grub_ieee1275_ihandle_t dev_ihandle = 0; + char *devpath; + /* XXX: This should be large enough for any possible case. */ + char prop[64]; + grub_ssize_t actual; + + devpath = grub_strndup (name, grub_strlen (name) + 2); + if (! devpath) + return grub_errno; + + /* To access the complete disk add `:0'. */ + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) + grub_strcat (devpath, ":0"); + + grub_dprintf ("disk", "Opening `%s'.\n", devpath); + + grub_ieee1275_open (devpath, &dev_ihandle); + if (! dev_ihandle) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + goto fail; + } + + grub_dprintf ("disk", "Opened `%s' as handle %p.\n", devpath, (void *) dev_ihandle); + + if (grub_ieee1275_finddevice (devpath, &dev)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read device properties"); + goto fail; + } + + if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop), + &actual)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read the device type"); + goto fail; + } + + if (grub_strcmp (prop, "block")) + { + grub_error (GRUB_ERR_BAD_DEVICE, "Not a block device"); + goto fail; + } + + /* XXX: There is no property to read the number of blocks. There + should be a property `#blocks', but it is not there. Perhaps it + is possible to use seek for this. */ + disk->total_sectors = 0xFFFFFFFFUL; + + /* XXX: Is it ok to use this? Perhaps it is better to use the path + or some property. */ + disk->id = dev; + + /* XXX: Read this, somehow. */ + disk->has_partitions = 1; + disk->data = (void *) dev_ihandle; + grub_free (devpath); + return 0; + + fail: + if (dev_ihandle) + grub_ieee1275_close (dev_ihandle); + grub_free (devpath); + return grub_errno; +} + +static void +grub_ofdisk_close (grub_disk_t disk) +{ + grub_dprintf ("disk", "Closing handle %p.\n", + (void *) disk->data); + grub_ieee1275_close ((grub_ieee1275_ihandle_t) disk->data); +} + +static grub_err_t +grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_ssize_t status, actual; + unsigned long long pos; + + grub_dprintf ("disk", + "Reading handle %p: sector 0x%llx, size 0x%lx, buf %p.\n", + (void *) disk->data, sector, (long) size, buf); + + pos = sector * 512UL; + + grub_ieee1275_seek ((grub_ieee1275_ihandle_t) disk->data, (int) (pos >> 32), + (int) pos & 0xFFFFFFFFUL, &status); + if (status < 0) + return grub_error (GRUB_ERR_READ_ERROR, + "Seek error, can't seek block %llu", + sector); + grub_ieee1275_read ((grub_ieee1275_ihandle_t) disk->data, buf, + size * 512UL, &actual); + if (actual != actual) + return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu", + sector); + + return 0; +} + +static grub_err_t +grub_ofdisk_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static struct grub_disk_dev grub_ofdisk_dev = + { + .name = "ofdisk", + .id = GRUB_DISK_DEVICE_OFDISK_ID, + .iterate = grub_ofdisk_iterate, + .open = grub_ofdisk_open, + .close = grub_ofdisk_close, + .read = grub_ofdisk_read, + .write = grub_ofdisk_write, + .next = 0 + }; + +void +grub_ofdisk_init (void) +{ + grub_disk_dev_register (&grub_ofdisk_dev); +} + +void +grub_ofdisk_fini (void) +{ + grub_disk_dev_unregister (&grub_ofdisk_dev); +} diff --git a/disk/loopback.c b/disk/loopback.c new file mode 100644 index 0000000..709c422 --- /dev/null +++ b/disk/loopback.c @@ -0,0 +1,258 @@ +/* loopback.c - command to add loopback devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +struct grub_loopback +{ + char *devname; + char *filename; + int has_partitions; + struct grub_loopback *next; +}; + +static struct grub_loopback *loopback_list; + +static const struct grub_arg_option options[] = + { + {"delete", 'd', 0, "delete the loopback device entry", 0, 0}, + {"partitions", 'p', 0, "simulate a hard drive with partitions", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +/* Delete the loopback device NAME. */ +static grub_err_t +delete_loopback (const char *name) +{ + struct grub_loopback *dev; + struct grub_loopback **prev; + + /* Search for the device. */ + for (dev = loopback_list, prev = &loopback_list; + dev; + prev = &dev->next, dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found"); + + /* Remove the device from the list. */ + *prev = dev->next; + + grub_free (dev->devname); + grub_free (dev->filename); + grub_free (dev); + + return 0; +} + +/* The command to add and remove loopback devices. */ +static grub_err_t +grub_cmd_loopback (struct grub_arg_list *state, + int argc, char **args) +{ + grub_file_t file; + struct grub_loopback *newdev; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + /* Check if `-d' was used. */ + if (state[0].set) + return delete_loopback (args[0]); + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + file = grub_file_open (args[1]); + if (! file) + return grub_errno; + + /* Close the file, the only reason for opening it is validation. */ + grub_file_close (file); + + /* First try to replace the old device. */ + for (newdev = loopback_list; newdev; newdev = newdev->next) + if (grub_strcmp (newdev->devname, args[0]) == 0) + break; + + if (newdev) + { + char *newname = grub_strdup (args[1]); + if (! newname) + return grub_errno; + + grub_free (newdev->filename); + newdev->filename = newname; + + /* Set has_partitions when `--partitions' was used. */ + newdev->has_partitions = state[1].set; + + return 0; + } + + /* Unable to replace it, make a new entry. */ + newdev = grub_malloc (sizeof (struct grub_loopback)); + if (! newdev) + return grub_errno; + + newdev->devname = grub_strdup (args[0]); + if (! newdev->devname) + { + grub_free (newdev); + return grub_errno; + } + + newdev->filename = grub_strdup (args[1]); + if (! newdev->filename) + { + grub_free (newdev->devname); + grub_free (newdev); + return grub_errno; + } + + /* Set has_partitions when `--partitions' was used. */ + newdev->has_partitions = state[1].set; + + /* Add the new entry to the list. */ + newdev->next = loopback_list; + loopback_list = newdev; + + return 0; +} + + +static int +grub_loopback_iterate (int (*hook) (const char *name)) +{ + struct grub_loopback *d; + for (d = loopback_list; d; d = d->next) + { + if (hook (d->devname)) + return 1; + } + return 0; +} + +static grub_err_t +grub_loopback_open (const char *name, grub_disk_t disk) +{ + grub_file_t file; + struct grub_loopback *dev; + + for (dev = loopback_list; dev; dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + + file = grub_file_open (dev->filename); + if (! file) + return grub_errno; + + /* Use the filesize for the disk size, round up to a complete sector. */ + disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1) + / GRUB_DISK_SECTOR_SIZE); + disk->id = (unsigned long) dev; + + disk->has_partitions = dev->has_partitions; + disk->data = file; + + return 0; +} + +static void +grub_loopback_close (grub_disk_t disk) +{ + grub_file_t file = (grub_file_t) disk->data; + + grub_file_close (file); +} + +static grub_err_t +grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_file_t file = (grub_file_t) disk->data; + grub_off_t pos; + + grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS); + + grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS); + if (grub_errno) + return grub_errno; + + /* In case there is more data read than there is available, in case + of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill + the rest with zeros. */ + pos = (sector + size) << GRUB_DISK_SECTOR_BITS; + if (pos > file->size) + { + grub_size_t amount = pos - file->size; + grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount); + } + + return 0; +} + +static grub_err_t +grub_loopback_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static struct grub_disk_dev grub_loopback_dev = + { + .name = "loopback", + .id = GRUB_DISK_DEVICE_LOOPBACK_ID, + .iterate = grub_loopback_iterate, + .open = grub_loopback_open, + .close = grub_loopback_close, + .read = grub_loopback_read, + .write = grub_loopback_write, + .next = 0 + }; + + + +GRUB_MOD_INIT(loop) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH, + "loopback [-d|-p] DEVICENAME FILE", + "Make a device of a file.", options); + grub_disk_dev_register (&grub_loopback_dev); +} + +GRUB_MOD_FINI(loop) +{ + grub_unregister_command ("loopback"); + grub_disk_dev_unregister (&grub_loopback_dev); +} diff --git a/disk/lvm.c b/disk/lvm.c new file mode 100644 index 0000000..6ebde63 --- /dev/null +++ b/disk/lvm.c @@ -0,0 +1,619 @@ +/* lvm.c - module to read Logical Volumes. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static struct grub_lvm_vg *vg_list; +static int lv_count; + + +/* Go the string STR and return the number after STR. *P will point + at the number. In case STR is not found, *P will be NULL and the + return value will be 0. */ +static int +grub_lvm_getvalue (char **p, char *str) +{ + *p = grub_strstr (*p, str); + if (! *p) + return 0; + *p += grub_strlen (str); + return grub_strtoul (*p, NULL, 10); +} + +static int +grub_lvm_iterate (int (*hook) (const char *name)) +{ + struct grub_lvm_vg *vg; + for (vg = vg_list; vg; vg = vg->next) + { + struct grub_lvm_lv *lv; + if (vg->lvs) + for (lv = vg->lvs; lv; lv = lv->next) + if (hook (lv->name)) + return 1; + } + + return 0; +} + +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_lvm_memberlist (grub_disk_t disk) +{ + struct grub_lvm_lv *lv = disk->data; + grub_disk_memberlist_t list = NULL, tmp; + struct grub_lvm_pv *pv; + + if (lv->vg->pvs) + for (pv = lv->vg->pvs; pv; pv = pv->next) + { + tmp = grub_malloc (sizeof (*tmp)); + tmp->disk = pv->disk; + tmp->next = list; + list = tmp; + } + + return list; +} +#endif + +static grub_err_t +grub_lvm_open (const char *name, grub_disk_t disk) +{ + struct grub_lvm_vg *vg; + struct grub_lvm_lv *lv = NULL; + for (vg = vg_list; vg; vg = vg->next) + { + if (vg->lvs) + for (lv = vg->lvs; lv; lv = lv->next) + if (! grub_strcmp (lv->name, name)) + break; + + if (lv) + break; + } + + if (! lv) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown LVM device %s", name); + + disk->has_partitions = 0; + disk->id = lv->number; + disk->data = lv; + disk->total_sectors = lv->size; + + return 0; +} + +static void +grub_lvm_close (grub_disk_t disk __attribute ((unused))) +{ + return; +} + +static grub_err_t +grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_err_t err = 0; + struct grub_lvm_lv *lv = disk->data; + struct grub_lvm_vg *vg = lv->vg; + struct grub_lvm_segment *seg = lv->segments; + struct grub_lvm_pv *pv; + grub_uint64_t offset; + grub_uint64_t extent; + unsigned int i; + + extent = grub_divmod64 (sector, vg->extent_size, NULL); + + /* Find the right segment. */ + for (i = 0; i < lv->segment_count; i++) + { + if ((seg->start_extent <= extent) + && ((seg->start_extent + seg->extent_count) > extent)) + { + break; + } + + seg++; + } + + if (seg->stripe_count == 1) + { + /* This segment is linear, so that's easy. We just need to find + out the offset in the physical volume and read SIZE bytes + from that. */ + struct grub_lvm_stripe *stripe = seg->stripes; + grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ + + pv = stripe->pv; + seg_offset = ((grub_uint64_t) stripe->start + * (grub_uint64_t) vg->extent_size) + pv->start; + + offset = sector - ((grub_uint64_t) seg->start_extent + * (grub_uint64_t) vg->extent_size) + seg_offset; + } + else + { + /* This is a striped segment. We have to find the right PV + similar to RAID0. */ + struct grub_lvm_stripe *stripe = seg->stripes; + grub_uint32_t a, b; + grub_uint64_t seg_offset; /* Offset of the segment in PV device. */ + unsigned int stripenr; + + offset = sector - ((grub_uint64_t) seg->start_extent + * (grub_uint64_t) vg->extent_size); + + a = grub_divmod64 (offset, seg->stripe_size, NULL); + grub_divmod64 (a, seg->stripe_count, &stripenr); + + a = grub_divmod64 (offset, seg->stripe_size * seg->stripe_count, NULL); + grub_divmod64 (offset, seg->stripe_size, &b); + offset = a * seg->stripe_size + b; + + stripe += stripenr; + pv = stripe->pv; + + seg_offset = ((grub_uint64_t) stripe->start + * (grub_uint64_t) vg->extent_size) + pv->start; + + offset += seg_offset; + } + + /* Check whether we actually know the physical volume we want to + read from. */ + if (pv->disk) + err = grub_disk_read (pv->disk, offset, 0, + size << GRUB_DISK_SECTOR_BITS, buf); + else + err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Physical volume %s not found", pv->name); + + return err; +} + +static grub_err_t +grub_lvm_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static int +grub_lvm_scan_device (const char *name) +{ + grub_err_t err; + grub_disk_t disk; + grub_uint64_t da_offset, da_size, mda_offset, mda_size; + char buf[GRUB_LVM_LABEL_SIZE]; + char vg_id[GRUB_LVM_ID_STRLEN+1]; + char pv_id[GRUB_LVM_ID_STRLEN+1]; + char *metadatabuf, *p, *q, *vgname; + struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf; + struct grub_lvm_pv_header *pvh; + struct grub_lvm_disk_locn *dlocn; + struct grub_lvm_mda_header *mdah; + struct grub_lvm_raw_locn *rlocn; + unsigned int i, j, vgname_len; + struct grub_lvm_vg *vg; + struct grub_lvm_pv *pv; + + disk = grub_disk_open (name); + if (!disk) + return 0; + + /* Search for label. */ + for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++) + { + err = grub_disk_read (disk, i, 0, sizeof(buf), buf); + if (err) + goto fail; + + if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID, + sizeof (lh->id))) + && (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL, + sizeof (lh->type)))) + break; + } + + /* Return if we didn't find a label. */ + if (i == GRUB_LVM_LABEL_SCAN_SECTORS) + goto fail; + + pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl)); + + for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++) + { + pv_id[j++] = pvh->pv_uuid[i]; + if ((i != 1) && (i != 29) && (i % 4 == 1)) + pv_id[j++] = '-'; + } + pv_id[j] = '\0'; + + dlocn = pvh->disk_areas_xl; + da_offset = grub_le_to_cpu64 (dlocn->offset); + da_size = grub_le_to_cpu64 (dlocn->size); + + dlocn++; + /* Is it possible to have multiple data/metadata areas? I haven't + seen devices that have it. */ + if (dlocn->offset) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "We don't support multiple data areas"); + + goto fail; + } + + dlocn++; + mda_offset = grub_le_to_cpu64 (dlocn->offset); + mda_size = grub_le_to_cpu64 (dlocn->size); + dlocn++; + + if (dlocn->offset) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "We don't support multiple metadata areas"); + + goto fail; + } + + /* Allocate buffer space for the circular worst-case scenario. */ + metadatabuf = grub_malloc (2 * mda_size); + if (! metadatabuf) + goto fail; + + err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf); + if (err) + goto fail2; + + mdah = (struct grub_lvm_mda_header *) metadatabuf; + if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC, + sizeof (mdah->magic))) + || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unknown metadata header"); + goto fail2; + } + + rlocn = mdah->raw_locns; + if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > + grub_le_to_cpu64 (mdah->size)) + { + /* Metadata is circular. Copy the wrap in place. */ + grub_memcpy (metadatabuf + mda_size, + metadatabuf + GRUB_LVM_MDA_HEADER_SIZE, + grub_le_to_cpu64 (rlocn->offset) + + grub_le_to_cpu64 (rlocn->size) - + grub_le_to_cpu64 (mdah->size)); + } + p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset); + + while (*q != ' ' && q < metadatabuf + mda_size) + q++; + + if (q == metadatabuf + mda_size) + goto fail2; + + vgname_len = q - p; + vgname = grub_malloc (vgname_len + 1); + if (!vgname) + goto fail2; + + grub_memcpy (vgname, p, vgname_len); + vgname[vgname_len] = '\0'; + + p = grub_strstr (q, "id = \""); + if (p == NULL) + goto fail3; + p += sizeof ("id = \"") - 1; + grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN); + vg_id[GRUB_LVM_ID_STRLEN] = '\0'; + + for (vg = vg_list; vg; vg = vg->next) + { + if (! grub_memcmp(vg_id, vg->id, GRUB_LVM_ID_STRLEN)) + break; + } + + if (! vg) + { + /* First time we see this volume group. We've to create the + whole volume group structure. */ + vg = grub_malloc (sizeof (*vg)); + if (! vg) + goto fail3; + vg->name = vgname; + grub_memcpy (vg->id, vg_id, GRUB_LVM_ID_STRLEN+1); + + vg->extent_size = grub_lvm_getvalue (&p, "extent_size = "); + if (p == NULL) + goto fail4; + + vg->lvs = NULL; + vg->pvs = NULL; + + p = grub_strstr (p, "physical_volumes {"); + if (p) + { + p += sizeof ("physical_volumes {") - 1; + + /* Add all the pvs to the volume group. */ + while (1) + { + int s; + while (grub_isspace (*p)) + p++; + + if (*p == '}') + break; + + pv = grub_malloc (sizeof (*pv)); + q = p; + while (*q != ' ') + q++; + + s = q - p; + pv->name = grub_malloc (s + 1); + grub_memcpy (pv->name, p, s); + pv->name[s] = '\0'; + + p = grub_strstr (p, "id = \""); + if (p == NULL) + goto pvs_fail; + p += sizeof("id = \"") - 1; + + grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN); + pv->id[GRUB_LVM_ID_STRLEN] = '\0'; + + pv->start = grub_lvm_getvalue (&p, "pe_start = "); + if (p == NULL) + goto pvs_fail; + + p = grub_strchr (p, '}'); + if (p == NULL) + goto pvs_fail; + p++; + + pv->disk = NULL; + pv->next = vg->pvs; + vg->pvs = pv; + + continue; + pvs_fail: + grub_free (pv->name); + grub_free (pv); + goto fail4; + } + } + + p = grub_strstr (p, "logical_volumes"); + if (p) + { + p += 18; + + /* And add all the lvs to the volume group. */ + while (1) + { + int s; + struct grub_lvm_lv *lv; + struct grub_lvm_segment *seg; + + while (grub_isspace (*p)) + p++; + + if (*p == '}') + break; + + lv = grub_malloc (sizeof (*lv)); + + q = p; + while (*q != ' ') + q++; + + s = q - p; + lv->name = grub_malloc (vgname_len + 1 + s + 1); + grub_memcpy (lv->name, vgname, vgname_len); + lv->name[vgname_len] = '-'; + grub_memcpy (lv->name + vgname_len + 1, p, s); + lv->name[vgname_len + 1 + s] = '\0'; + + lv->size = 0; + + lv->segment_count = grub_lvm_getvalue (&p, "segment_count = "); + if (p == NULL) + goto lvs_fail; + lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count); + seg = lv->segments; + + for (i = 0; i < lv->segment_count; i++) + { + struct grub_lvm_stripe *stripe; + + p = grub_strstr (p, "segment"); + if (p == NULL) + goto lvs_segment_fail; + + seg->start_extent = grub_lvm_getvalue (&p, "start_extent = "); + if (p == NULL) + goto lvs_segment_fail; + seg->extent_count = grub_lvm_getvalue (&p, "extent_count = "); + if (p == NULL) + goto lvs_segment_fail; + seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = "); + if (p == NULL) + goto lvs_segment_fail; + + lv->size += seg->extent_count * vg->extent_size; + + if (seg->stripe_count != 1) + seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); + + seg->stripes = grub_malloc (sizeof (*stripe) + * seg->stripe_count); + stripe = seg->stripes; + + p = grub_strstr (p, "stripes = ["); + if (p == NULL) + goto lvs_segment_fail2; + p += sizeof("stripes = [") - 1; + + for (j = 0; j < seg->stripe_count; j++) + { + char *pvname; + + p = grub_strchr (p, '"'); + if (p == NULL) + continue; + q = ++p; + while (*q != '"') + q++; + + s = q - p; + + pvname = grub_malloc (s + 1); + if (pvname == NULL) + goto lvs_segment_fail2; + + grub_memcpy (pvname, p, s); + pvname[s] = '\0'; + + if (vg->pvs) + for (pv = vg->pvs; pv; pv = pv->next) + { + if (! grub_strcmp (pvname, pv->name)) + { + stripe->pv = pv; + break; + } + } + + grub_free(pvname); + + stripe->start = grub_lvm_getvalue (&p, ","); + if (p == NULL) + continue; + + stripe++; + } + + seg++; + + continue; + lvs_segment_fail2: + grub_free (seg->stripes); + lvs_segment_fail: + goto fail4; + } + + p = grub_strchr (p, '}'); + if (p == NULL) + goto lvs_fail; + p += 3; + + lv->number = lv_count++; + lv->vg = vg; + lv->next = vg->lvs; + vg->lvs = lv; + + continue; + lvs_fail: + grub_free (lv->name); + grub_free (lv); + goto fail4; + } + } + + vg->next = vg_list; + vg_list = vg; + } + else + { + grub_free (vgname); + } + + /* Match the device we are currently reading from with the right + PV. */ + if (vg->pvs) + for (pv = vg->pvs; pv; pv = pv->next) + { + if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN)) + { + pv->disk = grub_disk_open (name); + break; + } + } + + goto fail2; + + /* Failure path. */ + fail4: + grub_free (vg); + fail3: + grub_free (vgname); + + /* Normal exit path. */ + fail2: + grub_free (metadatabuf); + fail: + grub_disk_close (disk); + return 0; +} + +static struct grub_disk_dev grub_lvm_dev = + { + .name = "lvm", + .id = GRUB_DISK_DEVICE_LVM_ID, + .iterate = grub_lvm_iterate, + .open = grub_lvm_open, + .close = grub_lvm_close, + .read = grub_lvm_read, + .write = grub_lvm_write, +#ifdef GRUB_UTIL + .memberlist = grub_lvm_memberlist, +#endif + .next = 0 + }; + + +GRUB_MOD_INIT(lvm) +{ + grub_device_iterate (&grub_lvm_scan_device); + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_disk_dev_register (&grub_lvm_dev); +} + +GRUB_MOD_FINI(lvm) +{ + grub_disk_dev_unregister (&grub_lvm_dev); + /* FIXME: free the lvm list. */ +} diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c new file mode 100644 index 0000000..f5eb84c --- /dev/null +++ b/disk/mdraid_linux.c @@ -0,0 +1,233 @@ +/* mdraid_linux.c - module to handle linux softraid. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Linux RAID on disk structures and constants, + copied from include/linux/raid/md_p.h. */ + +#define RESERVED_BYTES (64 * 1024) +#define RESERVED_SECTORS (RESERVED_BYTES / 512) + +#define NEW_SIZE_SECTORS(x) ((x & ~(RESERVED_SECTORS - 1)) \ + - RESERVED_SECTORS) + +#define SB_BYTES 4096 +#define SB_WORDS (SB_BYTES / 4) +#define SB_SECTORS (SB_BYTES / 512) + +/* + * The following are counted in 32-bit words + */ +#define SB_GENERIC_OFFSET 0 + +#define SB_PERSONALITY_OFFSET 64 +#define SB_DISKS_OFFSET 128 +#define SB_DESCRIPTOR_OFFSET 992 + +#define SB_GENERIC_CONSTANT_WORDS 32 +#define SB_GENERIC_STATE_WORDS 32 +#define SB_GENERIC_WORDS (SB_GENERIC_CONSTANT_WORDS + \ + SB_GENERIC_STATE_WORDS) + +#define SB_PERSONALITY_WORDS 64 +#define SB_DESCRIPTOR_WORDS 32 +#define SB_DISKS 27 +#define SB_DISKS_WORDS (SB_DISKS * SB_DESCRIPTOR_WORDS) + +#define SB_RESERVED_WORDS (1024 \ + - SB_GENERIC_WORDS \ + - SB_PERSONALITY_WORDS \ + - SB_DISKS_WORDS \ + - SB_DESCRIPTOR_WORDS) + +#define SB_EQUAL_WORDS (SB_GENERIC_WORDS \ + + SB_PERSONALITY_WORDS \ + + SB_DISKS_WORDS) + +/* + * Device "operational" state bits + */ +#define DISK_FAULTY 0 +#define DISK_ACTIVE 1 +#define DISK_SYNC 2 +#define DISK_REMOVED 3 + +#define DISK_WRITEMOSTLY 9 + +#define SB_MAGIC 0xa92b4efc + +/* + * Superblock state bits + */ +#define SB_CLEAN 0 +#define SB_ERRORS 1 + +#define SB_BITMAP_PRESENT 8 + +struct grub_raid_disk_09 +{ + grub_uint32_t number; /* Device number in the entire set. */ + grub_uint32_t major; /* Device major number. */ + grub_uint32_t minor; /* Device minor number. */ + grub_uint32_t raid_disk; /* The role of the device in the raid set. */ + grub_uint32_t state; /* Operational state. */ + grub_uint32_t reserved[SB_DESCRIPTOR_WORDS - 5]; +}; + +struct grub_raid_super_09 +{ + /* + * Constant generic information + */ + grub_uint32_t md_magic; /* MD identifier. */ + grub_uint32_t major_version; /* Major version. */ + grub_uint32_t minor_version; /* Minor version. */ + grub_uint32_t patch_version; /* Patchlevel version. */ + grub_uint32_t gvalid_words; /* Number of used words in this section. */ + grub_uint32_t set_uuid0; /* Raid set identifier. */ + grub_uint32_t ctime; /* Creation time. */ + grub_uint32_t level; /* Raid personality. */ + grub_uint32_t size; /* Apparent size of each individual disk. */ + grub_uint32_t nr_disks; /* Total disks in the raid set. */ + grub_uint32_t raid_disks; /* Disks in a fully functional raid set. */ + grub_uint32_t md_minor; /* Preferred MD minor device number. */ + grub_uint32_t not_persistent; /* Does it have a persistent superblock. */ + grub_uint32_t set_uuid1; /* Raid set identifier #2. */ + grub_uint32_t set_uuid2; /* Raid set identifier #3. */ + grub_uint32_t set_uuid3; /* Raid set identifier #4. */ + grub_uint32_t gstate_creserved[SB_GENERIC_CONSTANT_WORDS - 16]; + + /* + * Generic state information + */ + grub_uint32_t utime; /* Superblock update time. */ + grub_uint32_t state; /* State bits (clean, ...). */ + grub_uint32_t active_disks; /* Number of currently active disks. */ + grub_uint32_t working_disks; /* Number of working disks. */ + grub_uint32_t failed_disks; /* Number of failed disks. */ + grub_uint32_t spare_disks; /* Number of spare disks. */ + grub_uint32_t sb_csum; /* Checksum of the whole superblock. */ + grub_uint64_t events; /* Superblock update count. */ + grub_uint64_t cp_events; /* Checkpoint update count. */ + grub_uint32_t recovery_cp; /* Recovery checkpoint sector count. */ + grub_uint32_t gstate_sreserved[SB_GENERIC_STATE_WORDS - 12]; + + /* + * Personality information + */ + grub_uint32_t layout; /* The array's physical layout. */ + grub_uint32_t chunk_size; /* Chunk size in bytes. */ + grub_uint32_t root_pv; /* LV root PV. */ + grub_uint32_t root_block; /* LV root block. */ + grub_uint32_t pstate_reserved[SB_PERSONALITY_WORDS - 4]; + + /* + * Disks information + */ + struct grub_raid_disk_09 disks[SB_DISKS]; + + /* + * Reserved + */ + grub_uint32_t reserved[SB_RESERVED_WORDS]; + + /* + * Active descriptor + */ + struct grub_raid_disk_09 this_disk; +} __attribute__ ((packed)); + +static grub_err_t +grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) +{ + grub_disk_addr_t sector; + grub_uint64_t size; + struct grub_raid_super_09 sb; + grub_uint32_t *uuid; + + /* The sector where the RAID superblock is stored, if available. */ + size = grub_disk_get_size (disk); + sector = NEW_SIZE_SECTORS (size); + + if (grub_disk_read (disk, sector, 0, SB_BYTES, (char *) &sb)) + return grub_errno; + + /* Look whether there is a RAID superblock. */ + if (sb.md_magic != SB_MAGIC) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid"); + + /* FIXME: Also support version 1.0. */ + if (sb.major_version != 0 || sb.minor_version != 90) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID version: %d.%d", + sb.major_version, sb.minor_version); + + /* FIXME: Check the checksum. */ + + /* Multipath. */ + if ((int) sb.level == -4) + sb.level = 1; + + if (sb.level != 0 && sb.level != 1 && sb.level != 4 && + sb.level != 5 && sb.level != 6 && sb.level != 10) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported RAID level: %d", sb.level); + + array->number = sb.md_minor; + array->level = sb.level; + array->layout = sb.layout; + array->total_devs = sb.raid_disks; + array->disk_size = (sb.size) ? sb.size * 2 : sector; + array->chunk_size = sb.chunk_size >> 9; + array->index = sb.this_disk.number; + array->uuid_len = 16; + array->uuid = grub_malloc (16); + if (!array->uuid) + return grub_errno; + + uuid = (grub_uint32_t *) array->uuid; + uuid[0] = sb.set_uuid0; + uuid[1] = sb.set_uuid1; + uuid[2] = sb.set_uuid2; + uuid[3] = sb.set_uuid3; + + return 0; +} + +static struct grub_raid grub_mdraid_dev = { + .name = "mdraid", + .detect = grub_mdraid_detect, + .next = 0 +}; + +GRUB_MOD_INIT (mdraid) +{ + grub_raid_register (&grub_mdraid_dev); +} + +GRUB_MOD_FINI (mdraid) +{ + grub_raid_register (&grub_mdraid_dev); +} diff --git a/disk/memdisk.c b/disk/memdisk.c new file mode 100644 index 0000000..978eae5 --- /dev/null +++ b/disk/memdisk.c @@ -0,0 +1,117 @@ +/* memdisk.c - Access embedded memory disk. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static char *memdisk_addr; +static grub_off_t memdisk_size = 0; + +static int +grub_memdisk_iterate (int (*hook) (const char *name)) +{ + return hook ("memdisk"); +} + +static grub_err_t +grub_memdisk_open (const char *name, grub_disk_t disk) +{ + if (grub_strcmp (name, "memdisk")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a memdisk"); + + disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE; + disk->id = (unsigned long) "mdsk"; + disk->has_partitions = 0; + + return GRUB_ERR_NONE; +} + +static void +grub_memdisk_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_memdisk_read (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_memcpy (buf, memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), size << GRUB_DISK_SECTOR_BITS); + return 0; +} + +static grub_err_t +grub_memdisk_write (grub_disk_t disk __attribute((unused)), grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + grub_memcpy (memdisk_addr + (sector << GRUB_DISK_SECTOR_BITS), buf, size << GRUB_DISK_SECTOR_BITS); + return 0; +} + +static struct grub_disk_dev grub_memdisk_dev = + { + .name = "memdisk", + .id = GRUB_DISK_DEVICE_MEMDISK_ID, + .iterate = grub_memdisk_iterate, + .open = grub_memdisk_open, + .close = grub_memdisk_close, + .read = grub_memdisk_read, + .write = grub_memdisk_write, + .next = 0 + }; + +GRUB_MOD_INIT(memdisk) +{ + auto int hook (struct grub_module_header *); + int hook (struct grub_module_header *header) + { + if (header->type == OBJ_TYPE_MEMDISK) + { + char *memdisk_orig_addr; + memdisk_orig_addr = (char *) header + sizeof (struct grub_module_header); + + grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); + + memdisk_size = header->size - sizeof (struct grub_module_header); + memdisk_addr = grub_malloc (memdisk_size); + + grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); + grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); + + grub_disk_dev_register (&grub_memdisk_dev); + return 1; + } + + return 0; + } + + grub_module_iterate (hook); +} + +GRUB_MOD_FINI(memdisk) +{ + if (! memdisk_size) + return; + grub_free (memdisk_addr); + grub_disk_dev_unregister (&grub_memdisk_dev); +} diff --git a/disk/raid.c b/disk/raid.c new file mode 100644 index 0000000..62cbcb5 --- /dev/null +++ b/disk/raid.c @@ -0,0 +1,723 @@ +/* raid.c - module to read RAID arrays. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Linked list of RAID arrays. */ +static struct grub_raid_array *array_list; +grub_raid5_recover_func_t grub_raid5_recover_func; +grub_raid6_recover_func_t grub_raid6_recover_func; + + +static char +grub_is_array_readable (struct grub_raid_array *array) +{ + switch (array->level) + { + case 0: + if (array->nr_devs == array->total_devs) + return 1; + break; + + case 1: + if (array->nr_devs >= 1) + return 1; + break; + + case 4: + case 5: + case 6: + case 10: + { + unsigned int n; + + if (array->level == 10) + { + n = array->layout & 0xFF; + if (n == 1) + n = (array->layout >> 8) & 0xFF; + + n--; + } + else + n = array->level / 3; + + if (array->nr_devs >= array->total_devs - n) + return 1; + + break; + } + } + + return 0; +} + +static int +grub_raid_iterate (int (*hook) (const char *name)) +{ + struct grub_raid_array *array; + + for (array = array_list; array != NULL; array = array->next) + { + if (grub_is_array_readable (array)) + if (hook (array->name)) + return 1; + } + + return 0; +} + +#ifdef GRUB_UTIL +static grub_disk_memberlist_t +grub_raid_memberlist (grub_disk_t disk) +{ + struct grub_raid_array *array = disk->data; + grub_disk_memberlist_t list = NULL, tmp; + unsigned int i; + + for (i = 0; i < array->total_devs; i++) + if (array->device[i]) + { + tmp = grub_malloc (sizeof (*tmp)); + tmp->disk = array->device[i]; + tmp->next = list; + list = tmp; + } + + return list; +} +#endif + +static grub_err_t +grub_raid_open (const char *name, grub_disk_t disk) +{ + struct grub_raid_array *array; + unsigned n; + + for (array = array_list; array != NULL; array = array->next) + { + if (!grub_strcmp (array->name, name)) + if (grub_is_array_readable (array)) + break; + } + + if (!array) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown RAID device %s", + name); + + disk->has_partitions = 1; + disk->id = array->number; + disk->data = array; + + grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld\n", name, + array->total_devs, (unsigned long long) array->disk_size); + + switch (array->level) + { + case 1: + disk->total_sectors = array->disk_size; + break; + + case 10: + n = array->layout & 0xFF; + if (n == 1) + n = (array->layout >> 8) & 0xFF; + + disk->total_sectors = grub_divmod64 (array->total_devs * + array->disk_size, + n, 0); + break; + + case 0: + case 4: + case 5: + case 6: + n = array->level / 3; + + disk->total_sectors = (array->total_devs - n) * array->disk_size; + break; + } + + grub_dprintf ("raid", "%s: level=%d, total_sectors=%lld\n", name, + array->level, (unsigned long long) disk->total_sectors); + + return 0; +} + +static void +grub_raid_close (grub_disk_t disk __attribute ((unused))) +{ + return; +} + +void +grub_raid_block_xor (char *buf1, char *buf2, int size) +{ + grub_size_t *p1, *p2; + + p1 = (grub_size_t *) buf1; + p2 = (grub_size_t *) buf2; + size /= GRUB_CPU_SIZEOF_VOID_P; + + while (size) + { + *(p1++) ^= *(p2++); + size--; + } +} + +static grub_err_t +grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + struct grub_raid_array *array = disk->data; + grub_err_t err = 0; + + switch (array->level) + { + case 0: + case 1: + case 10: + { + grub_disk_addr_t read_sector, far_ofs; + grub_uint32_t disknr, b, near, far, ofs; + + read_sector = grub_divmod64 (sector, array->chunk_size, &b); + far = ofs = near = 1; + far_ofs = 0; + + if (array->level == 1) + near = array->total_devs; + else if (array->level == 10) + { + near = array->layout & 0xFF; + far = (array->layout >> 8) & 0xFF; + if (array->layout >> 16) + { + ofs = far; + far_ofs = 1; + } + else + far_ofs = grub_divmod64 (array->disk_size, + far * array->chunk_size, 0); + + far_ofs *= array->chunk_size; + } + + read_sector = grub_divmod64 (read_sector * near, array->total_devs, + &disknr); + + ofs *= array->chunk_size; + read_sector *= ofs; + + while (1) + { + grub_size_t read_size; + unsigned int i, j; + + read_size = array->chunk_size - b; + if (read_size > size) + read_size = size; + + for (i = 0; i < near; i++) + { + unsigned int k; + + k = disknr; + for (j = 0; j < far; j++) + { + if (array->device[k]) + { + if (grub_errno == GRUB_ERR_READ_ERROR) + grub_errno = GRUB_ERR_NONE; + + err = grub_disk_read (array->device[k], + read_sector + j * far_ofs + b, + 0, + read_size << GRUB_DISK_SECTOR_BITS, + buf); + if (! err) + break; + else if (err != GRUB_ERR_READ_ERROR) + return err; + } + else + err = grub_error (GRUB_ERR_READ_ERROR, + "disk missing."); + + k++; + if (k == array->total_devs) + k = 0; + } + + if (! err) + break; + + disknr++; + if (disknr == array->total_devs) + { + disknr = 0; + read_sector += ofs; + } + } + + if (err) + return err; + + buf += read_size << GRUB_DISK_SECTOR_BITS; + size -= read_size; + if (! size) + break; + + b = 0; + disknr += (near - i); + while (disknr >= array->total_devs) + { + disknr -= array->total_devs; + read_sector += ofs; + } + } + break; + } + + case 4: + case 5: + case 6: + { + grub_disk_addr_t read_sector; + grub_uint32_t b, p, n, disknr, e; + + /* n = 1 for level 4 and 5, 2 for level 6. */ + n = array->level / 3; + + /* Find the first sector to read. */ + read_sector = grub_divmod64 (sector, array->chunk_size, &b); + read_sector = grub_divmod64 (read_sector, array->total_devs - n, + &disknr); + if (array->level >= 5) + { + grub_divmod64 (read_sector, array->total_devs, &p); + + if (! (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK)) + p = array->total_devs - 1 - p; + + if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) + { + disknr += p + n; + } + else + { + grub_uint32_t q; + + q = p + (n - 1); + if (q >= array->total_devs) + q -= array->total_devs; + + if (disknr >= p) + disknr += n; + else if (disknr >= q) + disknr += q + 1; + } + + if (disknr >= array->total_devs) + disknr -= array->total_devs; + } + else + p = array->total_devs - n; + + read_sector *= array->chunk_size; + + while (1) + { + grub_size_t read_size; + int next_level; + + read_size = array->chunk_size - b; + if (read_size > size) + read_size = size; + + e = 0; + if (array->device[disknr]) + { + /* Reset read error. */ + if (grub_errno == GRUB_ERR_READ_ERROR) + grub_errno = GRUB_ERR_NONE; + + err = grub_disk_read (array->device[disknr], + read_sector + b, 0, + read_size << GRUB_DISK_SECTOR_BITS, + buf); + + if ((err) && (err != GRUB_ERR_READ_ERROR)) + break; + e++; + } + else + err = GRUB_ERR_READ_ERROR; + + if (err) + { + if (array->nr_devs < array->total_devs - n + e) + break; + + grub_errno = GRUB_ERR_NONE; + if (array->level == 6) + { + err = ((grub_raid6_recover_func) ? + (*grub_raid6_recover_func) (array, disknr, p, + buf, read_sector + b, + read_size) : + grub_error (GRUB_ERR_BAD_DEVICE, + "raid6rec is not loaded")); + } + else + { + err = ((grub_raid5_recover_func) ? + (*grub_raid5_recover_func) (array, disknr, + buf, read_sector + b, + read_size) : + grub_error (GRUB_ERR_BAD_DEVICE, + "raid5rec is not loaded")); + } + + if (err) + break; + } + + buf += read_size << GRUB_DISK_SECTOR_BITS; + size -= read_size; + if (! size) + break; + + b = 0; + disknr++; + + if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) + { + if (disknr == array->total_devs) + disknr = 0; + + next_level = (disknr == p); + } + else + { + if (disknr == p) + disknr += n; + + next_level = (disknr >= array->total_devs); + } + + if (next_level) + { + read_sector += array->chunk_size; + + if (array->level >= 5) + { + if (array->layout & GRUB_RAID_LAYOUT_RIGHT_MASK) + p = (p == array->total_devs - 1) ? 0 : p + 1; + else + p = (p == 0) ? array->total_devs - 1 : p - 1; + + if (array->layout & GRUB_RAID_LAYOUT_SYMMETRIC_MASK) + { + disknr = p + n; + if (disknr >= array->total_devs) + disknr -= array->total_devs; + } + else + { + disknr -= array->total_devs; + if (disknr == p) + disknr += n; + } + } + else + disknr = 0; + } + } + } + break; + } + + return err; +} + +static grub_err_t +grub_raid_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + +static grub_err_t +insert_array (grub_disk_t disk, struct grub_raid_array *new_array, + const char *scanner_name) +{ + struct grub_raid_array *array = 0, *p; + + /* See whether the device is part of an array we have already seen a + device from. */ + for (p = array_list; p != NULL; p = p->next) + if ((p->uuid_len == new_array->uuid_len) && + (! grub_memcmp (p->uuid, new_array->uuid, p->uuid_len))) + { + grub_free (new_array->uuid); + array = p; + + /* Do some checks before adding the device to the array. */ + + /* FIXME: Check whether the update time of the superblocks are + the same. */ + + if (array->total_devs == array->nr_devs) + /* We found more members of the array than the array + actually has according to its superblock. This shouldn't + happen normally, but what is the sanest things to do in such + a case? */ + return grub_error (GRUB_ERR_BAD_NUMBER, + "array->nr_devs > array->total_devs (%d)?!?", + array->total_devs); + + if (array->device[new_array->index] != NULL) + /* We found multiple devices with the same number. Again, + this shouldn't happen.*/ + return grub_error (GRUB_ERR_BAD_NUMBER, + "Found two disks with the number %d?!?", + new_array->number); + + if (new_array->disk_size < array->disk_size) + array->disk_size = new_array->disk_size; + break; + } + + /* Add an array to the list if we didn't find any. */ + if (!array) + { + array = grub_malloc (sizeof (*array)); + if (!array) + { + grub_free (new_array->uuid); + return grub_errno; + } + + *array = *new_array; + array->nr_devs = 0; + grub_memset (&array->device, 0, sizeof (array->device)); + + /* Check whether we don't have multiple arrays with the same number. */ + for (p = array_list; p != NULL; p = p->next) + { + if (p->number == array->number) + break; + } + + if (p) + { + /* The number is already in use, so we need to find an new number. */ + int i = 0; + + while (1) + { + for (p = array_list; p != NULL; p = p->next) + { + if (p->number == i) + break; + } + + if (!p) + { + /* We found an unused number. */ + array->number = i; + break; + } + + i++; + } + } + + array->name = grub_malloc (13); + if (! array->name) + { + grub_free (array->uuid); + grub_free (array); + + return grub_errno; + } + + grub_sprintf (array->name, "md%d", array->number); + + grub_dprintf ("raid", "Found array %s (%s)\n", array->name, + scanner_name); + + /* Add our new array to the list. */ + array->next = array_list; + array_list = array; + + /* RAID 1 doestn't use a chunksize but code assumes one so set + one. */ + if (array->level == 1) + array->chunk_size = 64; + } + + /* Add the device to the array. */ + array->device[new_array->index] = disk; + array->nr_devs++; + + return 0; +} + +static grub_raid_t grub_raid_list; + +static void +grub_raid_scan_device (int head_only) +{ + auto int hook (const char *name); + int hook (const char *name) + { + grub_disk_t disk; + struct grub_raid_array array; + struct grub_raid *p; + + grub_dprintf ("raid", "Scanning for RAID devices\n"); + + disk = grub_disk_open (name); + if (!disk) + return 0; + + if (disk->total_sectors == ULONG_MAX) + { + grub_disk_close (disk); + return 0; + } + + for (p = grub_raid_list; p; p = p->next) + { + if (! p->detect (disk, &array)) + { + if (! insert_array (disk, &array, p->name)) + return 0; + + break; + } + + /* This error usually means it's not raid, no need to display + it. */ + if (grub_errno != GRUB_ERR_OUT_OF_RANGE) + grub_print_error (); + + grub_errno = GRUB_ERR_NONE; + if (head_only) + break; + } + + grub_disk_close (disk); + + return 0; + } + + grub_device_iterate (&hook); +} + +static void +free_array (void) +{ + struct grub_raid_array *array; + + array = array_list; + while (array) + { + struct grub_raid_array *p; + int i; + + p = array; + array = array->next; + + for (i = 0; i < GRUB_RAID_MAX_DEVICES; i++) + if (p->device[i]) + grub_disk_close (p->device[i]); + + grub_free (p->uuid); + grub_free (p->name); + grub_free (p); + } + + array_list = 0; +} + +void +grub_raid_register (grub_raid_t raid) +{ + raid->next = grub_raid_list; + grub_raid_list = raid; + grub_raid_scan_device (1); +} + +void +grub_raid_unregister (grub_raid_t raid) +{ + grub_raid_t *p, q; + + for (p = &grub_raid_list, q = *p; q; p = &(q->next), q = q->next) + if (q == raid) + { + *p = q->next; + break; + } +} + +void +grub_raid_rescan (void) +{ + free_array (); + grub_raid_scan_device (0); +} + +static struct grub_disk_dev grub_raid_dev = + { + .name = "raid", + .id = GRUB_DISK_DEVICE_RAID_ID, + .iterate = grub_raid_iterate, + .open = grub_raid_open, + .close = grub_raid_close, + .read = grub_raid_read, + .write = grub_raid_write, +#ifdef GRUB_UTIL + .memberlist = grub_raid_memberlist, +#endif + .next = 0 + }; + + +GRUB_MOD_INIT(raid) +{ + grub_disk_dev_register (&grub_raid_dev); +} + +GRUB_MOD_FINI(raid) +{ + grub_disk_dev_unregister (&grub_raid_dev); + free_array (); +} diff --git a/disk/raid5_recover.c b/disk/raid5_recover.c new file mode 100644 index 0000000..31cef88 --- /dev/null +++ b/disk/raid5_recover.c @@ -0,0 +1,72 @@ +/* raid5_recover.c - module to recover from faulty RAID4/5 arrays. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_raid5_recover (struct grub_raid_array *array, int disknr, + char *buf, grub_disk_addr_t sector, int size) +{ + char *buf2; + int i; + + size <<= GRUB_DISK_SECTOR_BITS; + buf2 = grub_malloc (size); + if (!buf2) + return grub_errno; + + grub_memset (buf, 0, size); + + for (i = 0; i < (int) array->total_devs; i++) + { + grub_err_t err; + + if (i == disknr) + continue; + + err = grub_disk_read (array->device[i], sector, 0, size, buf2); + + if (err) + { + grub_free (buf2); + return err; + } + + grub_raid_block_xor (buf, buf2, size); + } + + grub_free (buf2); + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(raid5rec) +{ + grub_raid5_recover_func = grub_raid5_recover; +} + +GRUB_MOD_FINI(raid5rec) +{ + grub_raid5_recover_func = 0; +} diff --git a/disk/raid6_recover.c b/disk/raid6_recover.c new file mode 100644 index 0000000..3cb08ab --- /dev/null +++ b/disk/raid6_recover.c @@ -0,0 +1,216 @@ +/* raid6_recover.c - module to recover from faulty RAID6 arrays. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_uint8_t raid6_table1[256][256]; +static grub_uint8_t raid6_table2[256][256]; + +static void +grub_raid_block_mul (grub_uint8_t mul, char *buf, int size) +{ + int i; + grub_uint8_t *p; + + p = (grub_uint8_t *) buf; + for (i = 0; i < size; i++, p++) + *p = raid6_table1[mul][*p]; +} + +static void +grub_raid6_init_table (void) +{ + int i, j; + + for (i = 0; i < 256; i++) + raid6_table1[i][1] = raid6_table1[1][i] = i; + + for (i = 2; i < 256; i++) + for (j = i; j < 256; j++) + { + int n; + grub_uint8_t c; + + n = i >> 1; + + c = raid6_table1[n][j]; + c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0); + if (i & 1) + c ^= j; + + raid6_table1[j][i] = raid6_table1[i][j] = c; + } + + raid6_table2[0][0] = 1; + for (i = 1; i < 256; i++) + raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2]; + + for (i = 0; i < 254; i++) + for (j = 0; j < 254; j++) + { + grub_uint8_t c, n; + int k; + + if (i == j) + continue; + + k = i - j; + if (k < 0) + k += 255; + + c = n = raid6_table2[k][k] ^ 1; + for (k = 0; k < 253; k++) + c = raid6_table1[c][n]; + + raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c]; + } +} + +static grub_err_t +grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, + char *buf, grub_disk_addr_t sector, int size) +{ + int i, q, pos; + int err[2], nerr; + char *pbuf = 0, *qbuf = 0; + + size <<= GRUB_DISK_SECTOR_BITS; + pbuf = grub_malloc (size); + if (!pbuf) + goto quit; + + qbuf = grub_malloc (size); + if (!qbuf) + goto quit; + + q = p + 1; + if (q == (int) array->total_devs) + q = 0; + + grub_memset (pbuf, 0, size); + grub_memset (qbuf, 0, size); + + pos = q + 1; + if (pos == (int) array->total_devs) + pos = 0; + + nerr = 1; + for (i = 0; i < (int) array->total_devs - 2; i++) + { + if (pos == disknr) + err[0] = i; + else + { + if ((array->device[pos]) && + (! grub_disk_read (array->device[pos], sector, 0, size, buf))) + { + grub_raid_block_xor (pbuf, buf, size); + grub_raid_block_mul (raid6_table2[i][i], buf, size); + grub_raid_block_xor (qbuf, buf, size); + } + else + { + if (nerr >= 2) + goto quit; + + err[nerr++] = i; + grub_errno = GRUB_ERR_NONE; + } + } + + pos++; + if (pos == (int) array->total_devs) + pos = 0; + } + + if (nerr == 1) + { + if ((array->device[p]) && + (! grub_disk_read (array->device[p], sector, 0, size, buf))) + { + grub_raid_block_xor (buf, pbuf, size); + goto quit; + } + + if (! array->device[q]) + { + grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore"); + goto quit; + } + + grub_errno = GRUB_ERR_NONE; + if (grub_disk_read (array->device[q], sector, 0, size, buf)) + goto quit; + + grub_raid_block_xor (buf, qbuf, size); + grub_raid_block_mul (raid6_table2[255 - err[0]][255 - err[0]], buf, + size); + } + else + { + grub_uint8_t c; + + if ((! array->device[p]) || (! array->device[q])) + { + grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore"); + goto quit; + } + + if (grub_disk_read (array->device[p], sector, 0, size, buf)) + goto quit; + + grub_raid_block_xor (pbuf, buf, size); + + if (grub_disk_read (array->device[q], sector, 0, size, buf)) + goto quit; + + grub_raid_block_xor (qbuf, buf, size); + + c = raid6_table2[err[1]][err[0]]; + grub_raid_block_mul (c, qbuf, size); + + c = raid6_table1[raid6_table2[err[1]][err[1]]][c]; + grub_raid_block_mul (c, pbuf, size); + + grub_raid_block_xor (pbuf, qbuf, size); + grub_memcpy (buf, pbuf, size); + } + +quit: + grub_free (pbuf); + grub_free (qbuf); + + return grub_errno; +} + +GRUB_MOD_INIT(raid6rec) +{ + grub_raid6_init_table (); + grub_raid6_recover_func = grub_raid6_recover; +} + +GRUB_MOD_FINI(raid6rec) +{ + grub_raid6_recover_func = 0; +} diff --git a/disk/scsi.c b/disk/scsi.c new file mode 100644 index 0000000..5dce288 --- /dev/null +++ b/disk/scsi.c @@ -0,0 +1,395 @@ +/* scsi.c - scsi support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static grub_scsi_dev_t grub_scsi_dev_list; + +void +grub_scsi_dev_register (grub_scsi_dev_t dev) +{ + dev->next = grub_scsi_dev_list; + grub_scsi_dev_list = dev; +} + +void +grub_scsi_dev_unregister (grub_scsi_dev_t dev) +{ + grub_scsi_dev_t *p, q; + + for (p = &grub_scsi_dev_list, q = *p; q; p = &(q->next), q = q->next) + if (q == dev) + { + *p = q->next; + break; + } +} + + +/* Determine the the device is removable and the type of the device + SCSI. */ +static grub_err_t +grub_scsi_inquiry (grub_scsi_t scsi) +{ + struct grub_scsi_inquiry iq; + struct grub_scsi_inquiry_data iqd; + grub_err_t err; + + iq.opcode = grub_scsi_cmd_inquiry; + iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + iq.reserved = 0; + iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ + iq.reserved2 = 0; + + err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, + sizeof (iqd), (char *) &iqd); + if (err) + return err; + + scsi->devtype = iqd.devtype & GRUB_SCSI_DEVTYPE_MASK; + scsi->removable = iqd.rmb >> GRUB_SCSI_REMOVABLE_BIT; + + return GRUB_ERR_NONE; +} + +/* Read the capacity and block size of SCSI. */ +static grub_err_t +grub_scsi_read_capacity (grub_scsi_t scsi) +{ + struct grub_scsi_read_capacity rc; + struct grub_scsi_read_capacity_data rcd; + grub_err_t err; + + rc.opcode = grub_scsi_cmd_read_capacity; + rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + grub_memset (rc.reserved, 0, sizeof (rc.reserved)); + + err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, + sizeof (rcd), (char *) &rcd); + if (err) + return err; + + scsi->size = grub_be_to_cpu32 (rcd.size); + scsi->blocksize = grub_be_to_cpu32 (rcd.blocksize); + + return GRUB_ERR_NONE; +} + +/* Send a SCSI request for DISK: read SIZE sectors starting with + sector SECTOR to BUF. */ +static grub_err_t +grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_scsi_t scsi; + struct grub_scsi_read10 rd; + + scsi = disk->data; + + rd.opcode = grub_scsi_cmd_read10; + rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + rd.lba = grub_cpu_to_be32 (sector); + rd.reserved = 0; + rd.size = grub_cpu_to_be16 (size); + rd.reserved2 = 0; + rd.pad = 0; + + return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); +} + +/* Send a SCSI request for DISK: read SIZE sectors starting with + sector SECTOR to BUF. */ +static grub_err_t +grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_scsi_t scsi; + struct grub_scsi_read12 rd; + + scsi = disk->data; + + rd.opcode = grub_scsi_cmd_read12; + rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + rd.lba = grub_cpu_to_be32 (sector); + rd.size = grub_cpu_to_be32 (size); + rd.reserved = 0; + rd.control = 0; + + return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); +} + +#if 0 +/* Send a SCSI request for DISK: write the data stored in BUF to SIZE + sectors starting with SECTOR. */ +static grub_err_t +grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_scsi_t scsi; + struct grub_scsi_write10 wr; + + scsi = disk->data; + + wr.opcode = grub_scsi_cmd_write10; + wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + wr.lba = grub_cpu_to_be32 (sector); + wr.reserved = 0; + wr.size = grub_cpu_to_be16 (size); + wr.reserved2 = 0; + wr.pad = 0; + + return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); +} + +/* Send a SCSI request for DISK: write the data stored in BUF to SIZE + sectors starting with SECTOR. */ +static grub_err_t +grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_scsi_t scsi; + struct grub_scsi_write10 wr; + + scsi = disk->data; + + wr.opcode = grub_scsi_cmd_write12; + wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + wr.lba = grub_cpu_to_be32 (sector); + wr.size = grub_cpu_to_be32 (size); + wr.reserved = 0; + wr.pad = 0; + + return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); +} +#endif + + +static int +grub_scsi_iterate (int (*hook) (const char *name)) +{ + grub_scsi_dev_t p; + + auto int scsi_iterate (const char *name, int luns); + + int scsi_iterate (const char *name, int luns) + { + char sname[40]; + int i; + + /* In case of a single LUN, just return `usbX'. */ + if (luns == 1) + return hook (name); + + /* In case of multiple LUNs, every LUN will get a prefix to + distinguish it. */ + for (i = 0; i < luns; i++) + { + grub_sprintf (sname, "%s%c", name, 'a' + i); + if (hook (sname)) + return 1; + } + return 0; + } + + for (p = grub_scsi_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (scsi_iterate)) + return 1; + + return 0; +} + +static grub_err_t +grub_scsi_open (const char *name, grub_disk_t disk) +{ + grub_scsi_dev_t p; + grub_scsi_t scsi; + grub_err_t err; + int len; + int lun; + + scsi = grub_malloc (sizeof (*scsi)); + if (! scsi) + return grub_errno; + + len = grub_strlen (name); + lun = name[len - 1] - 'a'; + + /* Try to detect a LUN ('a'-'z'), otherwise just use the first + LUN. */ + if (lun < 0 || lun > 26) + lun = 0; + + for (p = grub_scsi_dev_list; p; p = p->next) + { + if (! p->open (name, scsi)) + { + disk->id = (unsigned long) "scsi"; /* XXX */ + disk->data = scsi; + scsi->dev = p; + scsi->lun = lun; + scsi->name = grub_strdup (name); + if (! scsi->name) + { + return grub_errno; + } + + grub_dprintf ("scsi", "dev opened\n"); + + err = grub_scsi_inquiry (scsi); + if (err) + { + grub_dprintf ("scsi", "inquiry failed\n"); + return grub_errno; + } + + grub_dprintf ("scsi", "inquiry: devtype=0x%02x removable=%d\n", + scsi->devtype, scsi->removable); + + /* Try to be conservative about the device types + supported. */ + if (scsi->devtype != grub_scsi_devtype_direct + && scsi->devtype != grub_scsi_devtype_cdrom) + { + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "unknown SCSI device"); + } + + if (scsi->devtype == grub_scsi_devtype_cdrom) + disk->has_partitions = 0; + else + disk->has_partitions = 1; + + err = grub_scsi_read_capacity (scsi); + if (err) + { + grub_dprintf ("scsi", "READ CAPACITY failed\n"); + return grub_errno; + } + + /* SCSI blocks can be something else than 512, although GRUB + wants 512 byte blocks. */ + disk->total_sectors = ((scsi->size * scsi->blocksize) + << GRUB_DISK_SECTOR_BITS); + + grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n", + disk->total_sectors, scsi->blocksize); + + return GRUB_ERR_NONE; + } + } + + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a SCSI disk"); +} + +static void +grub_scsi_close (grub_disk_t disk) +{ + grub_scsi_t scsi; + + scsi = disk->data; + return scsi->dev->close (scsi); +} + +static grub_err_t +grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_scsi_t scsi; + + scsi = disk->data; + + /* SCSI sectors are variable in size. GRUB uses 512 byte + sectors. */ + if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE) + { + unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS; + if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unsupported SCSI block size"); + + grub_uint32_t sector_mod = 0; + sector = grub_divmod64 (sector, spb, §or_mod); + + if (! (sector_mod == 0 && size % spb == 0)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unaligned SCSI read not supported"); + + size /= spb; + } + + /* Depending on the type, select a read function. */ + switch (scsi->devtype) + { + case grub_scsi_devtype_direct: + return grub_scsi_read10 (disk, sector, size, buf); + + case grub_scsi_devtype_cdrom: + return grub_scsi_read12 (disk, sector, size, buf); + } + + /* XXX: Never reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_scsi_write (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + const char *buf __attribute((unused))) +{ +#if 0 + /* XXX: Not tested yet! */ + + /* XXX: This should depend on the device type? */ + return grub_scsi_write10 (disk, sector, size, buf); +#endif + return GRUB_ERR_NOT_IMPLEMENTED_YET; +} + + +static struct grub_disk_dev grub_scsi_dev = + { + .name = "scsi", + .id = GRUB_DISK_DEVICE_SCSI_ID, + .iterate = grub_scsi_iterate, + .open = grub_scsi_open, + .close = grub_scsi_close, + .read = grub_scsi_read, + .write = grub_scsi_write, + .next = 0 + }; + +GRUB_MOD_INIT(scsi) +{ + grub_disk_dev_register (&grub_scsi_dev); +} + +GRUB_MOD_FINI(scsi) +{ + grub_disk_dev_unregister (&grub_scsi_dev); +} diff --git a/disk/usbms.c b/disk/usbms.c new file mode 100644 index 0000000..d08256b --- /dev/null +++ b/disk/usbms.c @@ -0,0 +1,393 @@ +/* usbms.c - USB Mass Storage Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define GRUB_USBMS_DIRECTION_BIT 7 + +/* The USB Mass Storage Command Block Wrapper. */ +struct grub_usbms_cbw +{ + grub_uint32_t signature; + grub_uint32_t tag; + grub_uint32_t transfer_length; + grub_uint8_t flags; + grub_uint8_t lun; + grub_uint8_t length; + grub_uint8_t cbwcb[16]; +} __attribute__ ((packed)); + +struct grub_usbms_csw +{ + grub_uint32_t signature; + grub_uint32_t tag; + grub_uint32_t residue; + grub_uint8_t status; +} __attribute__ ((packed)); + +struct grub_usbms_dev +{ + struct grub_usb_device *dev; + + int luns; + + int interface; + struct grub_usb_desc_endp *in; + struct grub_usb_desc_endp *out; + + int in_maxsz; + int out_maxsz; + + struct grub_usbms_dev *next; +}; +typedef struct grub_usbms_dev *grub_usbms_dev_t; + +static grub_usbms_dev_t grub_usbms_dev_list; + +static int devcnt; + +static grub_err_t +grub_usbms_reset (grub_usb_device_t dev, int interface) +{ + return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); +} + +static void +grub_usbms_finddevs (void) +{ + auto int usb_iterate (grub_usb_device_t dev); + + int usb_iterate (grub_usb_device_t usbdev) + { + grub_usb_err_t err; + struct grub_usb_desc_device *descdev = &usbdev->descdev; + int i; + + if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0) + return 0; + + /* XXX: Just check configuration 0 for now. */ + for (i = 0; i < usbdev->config[0].descconf->numif; i++) + { + struct grub_usbms_dev *usbms; + struct grub_usb_desc_if *interf; + int j; + grub_uint8_t luns; + + interf = usbdev->config[0].interf[i].descif; + + /* If this is not a USB Mass Storage device with a supported + protocol, just skip it. */ + if (interf->class != GRUB_USB_CLASS_MASS_STORAGE + || interf->subclass != GRUB_USBMS_SUBCLASS_BULK + || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) + { + continue; + } + + devcnt++; + usbms = grub_malloc (sizeof (struct grub_usbms_dev)); + if (! usbms) + return 1; + + usbms->dev = usbdev; + usbms->interface = i; + usbms->in = NULL; + usbms->out = NULL; + + /* Iterate over all endpoints of this interface, at least a + IN and OUT bulk endpoint are required. */ + for (j = 0; j < interf->endpointcnt; j++) + { + struct grub_usb_desc_endp *endp; + endp = &usbdev->config[0].interf[i].descendp[j]; + + if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2) + { + /* Bulk IN endpoint. */ + usbms->in = endp; + grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + usbms->in_maxsz = endp->maxpacket; + } + else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) + { + /* Bulk OUT endpoint. */ + usbms->out = endp; + grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + usbms->out_maxsz = endp->maxpacket; + } + } + + if (!usbms->in || !usbms->out) + { + grub_free (usbms); + return 0; + } + + /* Query the amount of LUNs. */ + err = grub_usb_control_msg (usbdev, 0xA1, 254, + 0, i, 1, (char *) &luns); + if (err) + { + /* In case of a stall, clear the stall. */ + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3); + } + + /* Just set the amount of LUNs to one. */ + grub_errno = GRUB_ERR_NONE; + usbms->luns = 1; + } + else + usbms->luns = luns; + + /* XXX: Check the magic values, does this really make + sense? */ + grub_usb_control_msg (usbdev, (1 << 6) | 1, 255, + 0, i, 0, 0); + + /* XXX: To make Qemu work? */ + if (usbms->luns == 0) + usbms->luns = 1; + + usbms->next = grub_usbms_dev_list; + grub_usbms_dev_list = usbms; + + /* XXX: Activate the first configuration. */ + grub_usb_set_configuration (usbdev, 1); + + /* Bolk-Only Mass Storage Reset, after the reset commands + will be accepted. */ + grub_usbms_reset (usbdev, i); + + return 0; + } + + return 0; + } + + grub_usb_iterate (usb_iterate); +} + + + +static int +grub_usbms_iterate (int (*hook) (const char *name, int luns)) +{ + grub_usbms_dev_t p; + int cnt = 0; + + for (p = grub_usbms_dev_list; p; p = p->next) + { + char devname[20]; + grub_sprintf (devname, "usb%d", cnt); + + if (hook (devname, p->luns)) + return 1; + cnt++; + } + + return 0; +} + +static grub_err_t +grub_usbms_tranfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf, int read_write) +{ + struct grub_usbms_cbw cbw; + grub_usbms_dev_t dev = (grub_usbms_dev_t) scsi->data; + struct grub_usbms_csw status; + static grub_uint32_t tag = 0; + grub_usb_err_t err; + int retrycnt = 3; + + retry: + if (retrycnt == 0) + return err; + + /* Setup the request. */ + grub_memset (&cbw, 0, sizeof (cbw)); + cbw.signature = grub_cpu_to_le32 (0x43425355); + cbw.tag = tag++; + cbw.transfer_length = grub_cpu_to_le32 (size); + cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT; + cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + cbw.length = cmdsize; + grub_memcpy (cbw.cbwcb, cmd, cmdsize); + + /* Write the request. */ + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15, + sizeof (cbw), (char *) &cbw); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + goto retry; + } + return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");; + } + + /* Read/write the data. */ + if (read_write == 0) + { + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + goto retry; + } + return grub_error (GRUB_ERR_READ_ERROR, + "can't read from USB Mass Storage device"); + } + } + else + { + err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf); + grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + goto retry; + } + return grub_error (GRUB_ERR_WRITE_ERROR, + "can't write to USB Mass Storage device"); + } + } + + /* Read the status. */ + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, + sizeof (status), (char *) &status); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + goto retry; + } + return grub_error (GRUB_ERR_READ_ERROR, + "can't read status from USB Mass Storage device"); + } + + /* XXX: Magic and check this code. */ + if (status.status == 2) + { + /* XXX: Phase error, reset device. */ + grub_usbms_reset (dev->dev, dev->interface); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + + retrycnt--; + if (retrycnt) + goto retry; + } + + if (status.status) + return grub_error (GRUB_ERR_READ_ERROR, + "error communication with USB Mass Storage device"); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf) +{ + return grub_usbms_tranfer (scsi, cmdsize, cmd, size, buf, 0); +} + +static grub_err_t +grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf) +{ + return grub_usbms_tranfer (scsi, cmdsize, cmd, size, buf, 1); +} + +static grub_err_t +grub_usbms_open (const char *name, struct grub_scsi *scsi) +{ + grub_usbms_dev_t p; + int devnum; + int i = 0; + + if (grub_strncmp (name, "usb", 3)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "not a USB Mass Storage device"); + + devnum = grub_strtoul (name + 3, NULL, 10); + for (p = grub_usbms_dev_list; p; p = p->next) + { + /* Check if this is the devnumth device. */ + if (devnum == i) + { + scsi->data = p; + scsi->name = grub_strdup (name); + scsi->luns = p->luns; + if (! scsi->name) + return grub_errno; + + return GRUB_ERR_NONE; + } + + i++; + } + + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "not a USB Mass Storage device"); +} + +static void +grub_usbms_close (struct grub_scsi *scsi) +{ + grub_free (scsi->name); +} + +static struct grub_scsi_dev grub_usbms_dev = + { + .name = "usb", + .iterate = grub_usbms_iterate, + .open = grub_usbms_open, + .close = grub_usbms_close, + .read = grub_usbms_read, + .write = grub_usbms_write + }; + +GRUB_MOD_INIT(usbms) +{ + grub_usbms_finddevs (); + grub_scsi_dev_register (&grub_usbms_dev); +} + +GRUB_MOD_FINI(usbms) +{ + grub_scsi_dev_unregister (&grub_usbms_dev); +} diff --git a/docs/fdl.texi b/docs/fdl.texi new file mode 100644 index 0000000..fe78df8 --- /dev/null +++ b/docs/fdl.texi @@ -0,0 +1,452 @@ + +@node GNU Free Documentation License +@appendixsec GNU Free Documentation License + +@cindex FDL, GNU Free Documentation License +@center Version 1.2, November 2002 + +@display +Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +@sc{ascii} without markup, Texinfo input format, La@TeX{} input +format, @acronym{SGML} or @acronym{XML} using a publicly available +@acronym{DTD}, and standard-conforming simple @acronym{HTML}, +PostScript or @acronym{PDF} designed for human modification. Examples +of transparent image formats include @acronym{PNG}, @acronym{XCF} and +@acronym{JPG}. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, @acronym{SGML} or +@acronym{XML} for which the @acronym{DTD} and/or processing tools are +not generally available, and the machine-generated @acronym{HTML}, +PostScript or @acronym{PDF} produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. +@end enumerate + +@page +@appendixsubsec ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with...Texts.'' line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: + diff --git a/docs/grub.cfg b/docs/grub.cfg new file mode 100644 index 0000000..7f02727 --- /dev/null +++ b/docs/grub.cfg @@ -0,0 +1,69 @@ +# +# Sample GRUB configuration file +# + +# Boot automatically after 30 secs. +set timeout=30 + +# By default, boot the first entry. +set default=0 + +# Fallback to the second entry. +set fallback=1 + +# For booting GNU/Hurd +menuentry "GNU (aka GNU/Hurd)" { + set root=(hd0,1) + multiboot /boot/gnumach.gz root=device:hd0s1 + module /hurd/ext2fs.static --readonly \ + --multiboot-command-line='${kernel-command-line}' \ + --host-priv-port='${host-port}' \ + --device-master-port='${device-port}' \ + --exec-server-task='${exec-task}' -T typed '${root}' \ + '$(task-create)' '$(task-resume)' + module /lib/ld.so.1 /hurd/exec '$(exec-task=task-create)' +} + +# For booting GNU/Linux +menuentry "GNU/Linux" { + set root=(hd0,1) + linux /vmlinuz root=/dev/sda1 + initrd /initrd.img +} + +# For booting FreeBSD +menuentry "FreeBSD (or GNU/kFreeBSD), direct boot" { + set root=(hd0,1,a) + freebsd /boot/kernel/kernel + freebsd_loadenv /boot/device.hints + freebsd_module /boot/splash.bmp type=splash_image_data + set FreeBSD.vfs.root.mountfrom=ufs:ad0s1a +} +menuentry "FreeBSD (or GNU/kFreeBSD), via /boot/loader" { + set root=(hd0,1,a) + freebsd /boot/loader +} + +# For booting NetBSD +menuentry "NetBSD" { + set root=(hd0,1,a) + netbsd /netbsd +} + +# For booting OpenBSD +menuentry "OpenBSD" { + set root=(hd0,1,a) + openbsd /bsd +} + +# For booting Microsoft Windows +menuentry "Microsoft Windows" { + set root=(hd0,1) + chainloader +1 +} + +# Change the colors. +menuentry "Change the colors" { + set menu_color_normal=light-green/brown + set menu_color_highlight=red/blue +} diff --git a/docs/grub.texi b/docs/grub.texi new file mode 100644 index 0000000..b8f74a0 --- /dev/null +++ b/docs/grub.texi @@ -0,0 +1,3967 @@ +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename grub.info +@include version.texi +@settitle GNU GRUB Manual @value{VERSION} +@c Unify all our little indices for now. +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@syncodeindex pg cp +@syncodeindex tp cp +@c %**end of header + +@footnotestyle separate +@paragraphindent 3 +@finalout + +@copying +This manual is for GNU GRUB (version @value{VERSION}, +@value{UPDATED}). + +Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections. +@end quotation +@end copying + +@dircategory Kernel +@direntry +* GRUB: (grub). The GRand Unified Bootloader +* grub-install: (grub)Invoking grub-install. Install GRUB on your drive +* grub-md5-crypt: (grub)Invoking grub-md5-crypt. Encrypt a password + in MD5 format +* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo + command from a + terminfo name +* grub-set-default: (grub)Invoking grub-set-default. Set a default boot + entry +* mbchk: (grub)Invoking mbchk. Check for the format of a Multiboot kernel +@end direntry + +@setchapternewpage odd + +@titlepage +@sp 10 +@title the GNU GRUB manual +@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. +@author Gordon Matzigkeit +@author Yoshinori K. Okuji +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@c Output the table of contents at the beginning. +@contents + +@finalout +@headings double + +@ifnottex +@node Top +@top GNU GRUB manual + +This is the documentation of GNU GRUB, the GRand Unified Bootloader, +a flexible and powerful boot loader program for a wide range of +architectures. + +This edition documents version @value{VERSION}. + +@insertcopying +@end ifnottex + +@menu +* Introduction:: Capturing the spirit of GRUB +* Naming convention:: Names of your drives in GRUB +* Installation:: Installing GRUB on your drive +* Booting:: How to boot different operating systems +* Configuration:: Writing your own configuration file +* Network:: Downloading OS images from a network +* Serial terminal:: Using GRUB via a serial line +* Preset Menu:: Embedding a configuration file into GRUB +* Security:: Improving the security +* Images:: GRUB image files +* Filesystem:: Filesystem syntax and semantics +* Interface:: The menu and the command-line +* Commands:: The list of available builtin commands +* Troubleshooting:: Error messages produced by GRUB +* Invoking the grub shell:: How to use the grub shell +* Invoking grub-install:: How to use the GRUB installer +* Invoking grub-md5-crypt:: How to generate a cryptic password +* Invoking grub-terminfo:: How to generate a terminfo command +* Invoking grub-set-default:: How to set a default boot entry +* Invoking mbchk:: How to use the Multiboot checker +* Obtaining and Building GRUB:: How to obtain and build GRUB +* Reporting bugs:: Where you should send a bug report +* Future:: Some future plans on GRUB +* Internals:: Hacking GRUB +* Copying This Manual:: Copying This Manual +* Index:: +@end menu + + +@node Introduction +@chapter Introduction to GRUB + +@menu +* Overview:: What exactly GRUB is and how to use it +* History:: From maggot to house fly +* Features:: GRUB features +* Role of a boot loader:: The role of a boot loader +@end menu + + +@node Overview +@section Overview + +Briefly, a @dfn{boot loader} is the first software program that runs when +a computer starts. It is responsible for loading and transferring +control to an operating system @dfn{kernel} software (such as Linux or +GNU Mach). The kernel, in turn, initializes the rest of the operating +system (e.g. a GNU system). + +GNU GRUB is a very powerful boot loader, which can load a wide variety +of free operating systems, as well as proprietary operating systems with +chain-loading@footnote{@dfn{chain-load} is the mechanism for loading +unsupported operating systems by loading another boot loader. It is +typically used for loading DOS or Windows.}. GRUB is designed to +address the complexity of booting a personal computer; both the +program and this manual are tightly bound to that computer platform, +although porting to other platforms may be addressed in the future. + +One of the important features in GRUB is flexibility; GRUB understands +filesystems and kernel executable formats, so you can load an arbitrary +operating system the way you like, without recording the physical +position of your kernel on the disk. Thus you can load the kernel +just by specifying its file name and the drive and partition where the +kernel resides. + +When booting with GRUB, you can use either a command-line interface +(@pxref{Command-line interface}), or a menu interface (@pxref{Menu +interface}). Using the command-line interface, you type the drive +specification and file name of the kernel manually. In the menu +interface, you just select an OS using the arrow keys. The menu is +based on a configuration file which you prepare beforehand +(@pxref{Configuration}). While in the menu, you can switch to the +command-line mode, and vice-versa. You can even edit menu entries +before using them. + +In the following chapters, you will learn how to specify a drive, a +partition, and a file name (@pxref{Naming convention}) to GRUB, how to +install GRUB on your drive (@pxref{Installation}), and how to boot your +OSes (@pxref{Booting}), step by step. + +Besides the GRUB boot loader itself, there is a @dfn{grub shell} +@command{grub} (@pxref{Invoking the grub shell}) which can be run when +you are in your operating system. It emulates the boot loader and can +be used for installing the boot loader. + + +@node History +@section History of GRUB + +GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU +Hurd with the University of Utah's Mach 4 microkernel (now known as GNU +Mach). Erich and Brian Ford designed the Multiboot Specification +(@pxref{Top, Multiboot Specification, Motivation, multiboot, The Multiboot +Specification}), because they were determined not to add to the large +number of mutually-incompatible PC boot methods. + +Erich then began modifying the FreeBSD boot loader so that it would +understand Multiboot. He soon realized that it would be a lot easier +to write his own boot loader from scratch than to keep working on the +FreeBSD boot loader, and so GRUB was born. + +Erich added many features to GRUB, but other priorities prevented him +from keeping up with the demands of its quickly-expanding user base. In +1999, Gordon Matzigkeit and Yoshinori K. Okuji adopted GRUB as an +official GNU package, and opened its development by making the latest +sources available via anonymous CVS. @xref{Obtaining and Building +GRUB}, for more information. + + +@node Features +@section GRUB features + +The primary requirement for GRUB is that it be compliant with the +@dfn{Multiboot Specification}, which is described in @ref{Top, Multiboot +Specification, Motivation, multiboot, The Multiboot Specification}. + +The other goals, listed in approximate order of importance, are: + +@itemize @bullet{} +@item +Basic functions must be straightforward for end-users. + +@item +Rich functionality to support kernel experts and designers. + +@item +Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and +Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are +supported via a chain-loading function. +@end itemize + +Except for specific compatibility modes (chain-loading and the Linux +@dfn{piggyback} format), all kernels will be started in much the same +state as in the Multiboot Specification. Only kernels loaded at 1 megabyte +or above are presently supported. Any attempt to load below that +boundary will simply result in immediate failure and an error message +reporting the problem. + +In addition to the requirements above, GRUB has the following features +(note that the Multiboot Specification doesn't require all the features +that GRUB supports): + +@table @asis +@item Recognize multiple executable formats +Support many of the @dfn{a.out} variants plus @dfn{ELF}. Symbol +tables are also loaded. + +@item Support non-Multiboot kernels +Support many of the various free 32-bit kernels that lack Multiboot +compliance (primarily FreeBSD, NetBSD, OpenBSD, and +Linux). Chain-loading of other boot loaders is also supported. + +@item Load multiples modules +Fully support the Multiboot feature of loading multiple modules. + +@item Load a configuration file +Support a human-readable text configuration file with preset boot +commands. You can also load another configuration file dynamically and +embed a preset configuration file in a GRUB image file. The list of +commands (@pxref{Commands}) are a superset of those supported on the +command-line. An example configuration file is provided in +@ref{Configuration}. + +@item Provide a menu interface +A menu interface listing preset boot commands, with a programmable +timeout, is available. There is no fixed limit on the number of boot +entries, and the current implementation has space for several hundred. + +@item Have a flexible command-line interface +A fairly flexible command-line interface, accessible from the menu, +is available to edit any preset commands, or write a new boot command +set from scratch. If no configuration file is present, GRUB drops to +the command-line. + +The list of commands (@pxref{Commands}) are a subset of those supported +for configuration files. Editing commands closely resembles the Bash +command-line (@pxref{Command Line Editing, Bash, Command Line Editing, +features, Bash Features}), with @key{TAB}-completion of commands, +devices, partitions, and files in a directory depending on context. + +@item Support multiple filesystem types +Support multiple filesystem types transparently, plus a useful explicit +blocklist notation. The currently supported filesystem types are +@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux +ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa +fs}. @xref{Filesystem}, for more information. + +@item Support automatic decompression +Can decompress files which were compressed by @command{gzip}. This +function is both automatic and transparent to the user (i.e. all +functions operate upon the uncompressed contents of the specified +files). This greatly reduces a file size and loading time, a +particularly great benefit for floppies.@footnote{There are a few +pathological cases where loading a very badly organized ELF kernel might +take longer, but in practice this never happen.} + +It is conceivable that some kernel modules should be loaded in a +compressed state, so a different module-loading command can be specified +to avoid uncompressing the modules. + +@item Access data on any installed device +Support reading data from any or all floppies or hard disk(s) recognized +by the BIOS, independent of the setting of the root device. + +@item Be independent of drive geometry translations +Unlike many other boot loaders, GRUB makes the particular drive +translation irrelevant. A drive installed and running with one +translation may be converted to another translation without any adverse +effects or changes in GRUB's configuration. + +@item Detect all installed @sc{ram} +GRUB can generally find all the installed @sc{ram} on a PC-compatible +machine. It uses an advanced BIOS query technique for finding all +memory regions. As described on the Multiboot Specification (@pxref{Top, +Multiboot Specification, Motivation, multiboot, The Multiboot +Specification}), not all kernels make use of this information, but GRUB +provides it for those who do. + +@item Support Logical Block Address mode +In traditional disk calls (called @dfn{CHS mode}), there is a geometry +translation problem, that is, the BIOS cannot access over 1024 +cylinders, so the accessible space is limited to at least 508 MB and to +at most 8GB. GRUB can't universally solve this problem, as there is no +standard interface used in all machines. However, several newer machines +have the new interface, Logical Block Address (@dfn{LBA}) mode. GRUB +automatically detects if LBA mode is available and uses it if +available. In LBA mode, GRUB can access the entire disk. + +@item Support network booting +GRUB is basically a disk-based boot loader but also has network +support. You can load OS images from a network by using the @dfn{TFTP} +protocol. + +@item Support remote terminals +To support computers with no console, GRUB provides remote terminal +support, so that you can control GRUB from a remote host. Only serial +terminal support is implemented at the moment. +@end table + + +@node Role of a boot loader +@section The role of a boot loader + +The following is a quotation from Gordon Matzigkeit, a GRUB fanatic: + +@quotation +Some people like to acknowledge both the operating system and kernel when +they talk about their computers, so they might say they use +``GNU/Linux'' or ``GNU/Hurd''. Other people seem to think that the +kernel is the most important part of the system, so they like to call +their GNU operating systems ``Linux systems.'' + +I, personally, believe that this is a grave injustice, because the +@emph{boot loader} is the most important software of all. I used to +refer to the above systems as either ``LILO''@footnote{The LInux LOader, +a boot loader that everybody uses, but nobody likes.} or ``GRUB'' +systems. + +Unfortunately, nobody ever understood what I was talking about; now I +just use the word ``GNU'' as a pseudonym for GRUB. + +So, if you ever hear people talking about their alleged ``GNU'' systems, +remember that they are actually paying homage to the best boot loader +around@dots{} GRUB! +@end quotation + +We, the GRUB maintainers, do not (usually) encourage Gordon's level of +fanaticism, but it helps to remember that boot loaders deserve +recognition. We hope that you enjoy using GNU GRUB as much as we did +writing it. + + +@node Naming convention +@chapter Naming convention + +The device syntax used in GRUB is a wee bit different from what you may +have seen before in your operating system(s), and you need to know it so +that you can specify a drive/partition. + +Look at the following examples and explanations: + +@example +(fd0) +@end example + +First of all, GRUB requires that the device name be enclosed with +@samp{(} and @samp{)}. The @samp{fd} part means that it is a floppy +disk. The number @samp{0} is the drive number, which is counted from +@emph{zero}. This expression means that GRUB will use the whole floppy +disk. + +@example +(hd0,1) +@end example + +Here, @samp{hd} means it is a hard disk drive. The first integer +@samp{0} indicates the drive number, that is, the first hard disk, while +the second integer, @samp{1}, indicates the partition number (or the +@sc{pc} slice number in the BSD terminology). Once again, please note +that the partition numbers are counted from @emph{zero}, not from +one. This expression means the second partition of the first hard disk +drive. In this case, GRUB uses one partition of the disk, instead of the +whole disk. + +@example +(hd0,4) +@end example + +This specifies the first @dfn{extended partition} of the first hard disk +drive. Note that the partition numbers for extended partitions are +counted from @samp{4}, regardless of the actual number of primary +partitions on your hard disk. + +@example +(hd1,a) +@end example + +This means the BSD @samp{a} partition of the second hard disk. If you +need to specify which @sc{pc} slice number should be used, use something +like this: @samp{(hd1,0,a)}. If the @sc{pc} slice number is omitted, +GRUB searches for the first @sc{pc} slice which has a BSD @samp{a} +partition. + +Of course, to actually access the disks or partitions with GRUB, you +need to use the device specification in a command, like @samp{root +(fd0)} or @samp{unhide (hd0,2)}. To help you find out which number +specifies a partition you want, the GRUB command-line +(@pxref{Command-line interface}) options have argument +completion. This means that, for example, you only need to type + +@example +root ( +@end example + +followed by a @key{TAB}, and GRUB will display the list of drives, +partitions, or file names. So it should be quite easy to determine the +name of your target partition, even with minimal knowledge of the +syntax. + +Note that GRUB does @emph{not} distinguish IDE from SCSI - it simply +counts the drive numbers from zero, regardless of their type. Normally, +any IDE drive number is less than any SCSI drive number, although that +is not true if you change the boot sequence by swapping IDE and SCSI +drives in your BIOS. + +Now the question is, how to specify a file? Again, consider an +example: + +@example +(hd0,0)/vmlinuz +@end example + +This specifies the file named @samp{vmlinuz}, found on the first +partition of the first hard disk drive. Note that the argument +completion works with file names, too. + +That was easy, admit it. Now read the next chapter, to find out how to +actually install GRUB on your drive. + + +@node Installation +@chapter Installation + +In order to install GRUB as your boot loader, you need to first +install the GRUB system and utilities under your UNIX-like operating +system (@pxref{Obtaining and Building GRUB}). You can do this either +from the source tarball, or as a package for your OS. + +After you have done that, you need to install the boot loader on a +drive (floppy or hard disk). There are two ways of doing that - either +using the utility @command{grub-install} (@pxref{Invoking +grub-install}) on a UNIX-like OS, or by running GRUB itself from a +floppy. These are quite similar, however the utility might probe a +wrong BIOS drive, so you should be careful. + +Also, if you install GRUB on a UNIX-like OS, please make sure that you +have an emergency boot disk ready, so that you can rescue your computer +if, by any chance, your hard drive becomes unusable (unbootable). + +GRUB comes with boot images, which are normally put in the directory +@file{/usr/lib/grub/i386-pc}. If you do not use grub-install, then +you need to copy the files @file{stage1}, @file{stage2}, and +@file{*stage1_5} to the directory @file{/boot/grub}, and run the +@command{grub-set-default} (@pxref{Invoking grub-set-default}) if you +intend to use @samp{default saved} (@pxref{default}) in your +configuration file. Hereafter, the directory where GRUB images are +initially placed (normally @file{/usr/lib/grub/i386-pc}) will be +called the @dfn{image directory}, and the directory where the boot +loader needs to find them (usually @file{/boot/grub}) will be called +the @dfn{boot directory}. + +@menu +* Creating a GRUB boot floppy:: +* Installing GRUB natively:: +* Installing GRUB using grub-install:: +* Making a GRUB bootable CD-ROM:: +@end menu + + +@node Creating a GRUB boot floppy +@section Creating a GRUB boot floppy + +To create a GRUB boot floppy, you need to take the files @file{stage1} +and @file{stage2} from the image directory, and write them to the first +and the second block of the floppy disk, respectively. + +@strong{Caution:} This procedure will destroy any data currently stored +on the floppy. + +On a UNIX-like operating system, that is done with the following +commands: + +@example +@group +# @kbd{cd /usr/lib/grub/i386-pc} +# @kbd{dd if=stage1 of=/dev/fd0 bs=512 count=1} +1+0 records in +1+0 records out +# @kbd{dd if=stage2 of=/dev/fd0 bs=512 seek=1} +153+1 records in +153+1 records out +# +@end group +@end example + +The device file name may be different. Consult the manual for your OS. + + +@node Installing GRUB natively +@section Installing GRUB natively + +@strong{Caution:} Installing GRUB's stage1 in this manner will erase the +normal boot-sector used by an OS. + +GRUB can currently boot GNU Mach, Linux, FreeBSD, NetBSD, and OpenBSD +directly, so using it on a boot sector (the first sector of a +partition) should be okay. But generally, it would be a good idea to +back up the first sector of the partition on which you are installing +GRUB's stage1. This isn't as important if you are installing GRUB on +the first sector of a hard disk, since it's easy to reinitialize it +(e.g. by running @samp{FDISK /MBR} from DOS). + +If you decide to install GRUB in the native environment, which is +definitely desirable, you'll need to create a GRUB boot disk, and +reboot your computer with it. Otherwise, see @ref{Installing GRUB using +grub-install}. + +Once started, GRUB will show the command-line interface +(@pxref{Command-line interface}). First, set the GRUB's @dfn{root +device}@footnote{Note that GRUB's root device doesn't necessarily mean +your OS's root partition; if you need to specify a root partition for +your OS, add the argument into the command @command{kernel}.} to the +partition containing the boot directory, like this: + +@example +grub> @kbd{root (hd0,0)} +@end example + +If you are not sure which partition actually holds this directory, use the +command @command{find} (@pxref{find}), like this: + +@example +grub> @kbd{find /boot/grub/stage1} +@end example + +This will search for the file name @file{/boot/grub/stage1} and show the +devices which contain the file. + +Once you've set the root device correctly, run the command +@command{setup} (@pxref{setup}): + +@example +grub> @kbd{setup (hd0)} +@end example + +This command will install the GRUB boot loader on the Master Boot +Record (MBR) of the first drive. If you want to put GRUB into the boot +sector of a partition instead of putting it in the MBR, specify the +partition into which you want to install GRUB: + +@example +grub> @kbd{setup (hd0,0)} +@end example + +If you install GRUB into a partition or a drive other than the first +one, you must chain-load GRUB from another boot loader. Refer to the +manual for the boot loader to know how to chain-load GRUB. + +After using the setup command, you will boot into GRUB without the +GRUB floppy. See the chapter @ref{Booting} to find out how to boot +your operating systems from GRUB. + + +@node Installing GRUB using grub-install +@section Installing GRUB using grub-install + +@strong{Caution:} This procedure is definitely less safe, because +there are several ways in which your computer can become +unbootable. For example, most operating systems don't tell GRUB how to +map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses} +the mapping. This will succeed in most cases, but not +always. Therefore, GRUB provides you with a map file called the +@dfn{device map}, which you must fix if it is wrong. @xref{Device +map}, for more details. + +If you still do want to install GRUB under a UNIX-like OS (such +as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking +grub-install}) as the superuser (@dfn{root}). + +The usage is basically very simple. You only need to specify one +argument to the program, namely, where to install the boot loader. The +argument can be either a device file (like @samp{/dev/hda}) or a +partition specified in GRUB's notation. For example, under Linux the +following will install GRUB into the MBR of the first IDE disk: + +@example +# @kbd{grub-install /dev/hda} +@end example + +Likewise, under GNU/Hurd, this has the same effect: + +@example +# @kbd{grub-install /dev/hd0} +@end example + +If it is the first BIOS drive, this is the same as well: + +@example +# @kbd{grub-install '(hd0)'} +@end example + +Or you can omit the parentheses: + +@example +# @kbd{grub-install hd0} +@end example + +But all the above examples assume that GRUB should use images under +the root directory. If you want GRUB to use images under a directory +other than the root directory, you need to specify the option +@option{--root-directory}. The typical usage is that you create a GRUB +boot floppy with a filesystem. Here is an example: + +@example +@group +# @kbd{mke2fs /dev/fd0} +# @kbd{mount -t ext2 /dev/fd0 /mnt} +# @kbd{grub-install --root-directory=/mnt fd0} +# @kbd{umount /mnt} +@end group +@end example + +Another example is when you have a separate boot partition +which is mounted at @file{/boot}. Since GRUB is a boot loader, it +doesn't know anything about mountpoints at all. Thus, you need to run +@command{grub-install} like this: + +@example +# @kbd{grub-install --root-directory=/boot /dev/hda} +@end example + +By the way, as noted above, it is quite difficult to guess BIOS drives +correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt +you to check if it could really guess the correct mappings, after the +installation. The format is defined in @ref{Device map}. Please be +quite careful. If the output is wrong, it is unlikely that your +computer will be able to boot with no problem. + +Note that @command{grub-install} is actually just a shell script and the +real task is done by the grub shell @command{grub} (@pxref{Invoking the +grub shell}). Therefore, you may run @command{grub} directly to install +GRUB, without using @command{grub-install}. Don't do that, however, +unless you are very familiar with the internals of GRUB. Installing a +boot loader on a running OS may be extremely dangerous. + + +@node Making a GRUB bootable CD-ROM +@section Making a GRUB bootable CD-ROM + +GRUB supports the @dfn{no emulation mode} in the El Torito +specification@footnote{El Torito is a specification for bootable CD +using BIOS functions.}. This means that you can use the whole CD-ROM +from GRUB and you don't have to make a floppy or hard disk image file, +which can cause compatibility problems. + +For booting from a CD-ROM, GRUB uses a special Stage 2 called +@file{stage2_eltorito}. The only GRUB files you need to have in your +bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file +@file{menu.lst}. You don't need to use @file{stage1} or @file{stage2}, +because El Torito is quite different from the standard boot process. + +Here is an example of procedures to make a bootable CD-ROM +image. First, make a top directory for the bootable image, say, +@samp{iso}: + +@example +$ @kbd{mkdir iso} +@end example + +Make a directory for GRUB: + +@example +$ @kbd{mkdir -p iso/boot/grub} +@end example + +Copy the file @file{stage2_eltorito}: + +@example +$ @kbd{cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub} +@end example + +If desired, make the config file @file{menu.lst} under @file{iso/boot/grub} +(@pxref{Configuration}), and copy any files and directories for the disc to the +directory @file{iso/}. + +Finally, make a ISO9660 image file like this: + +@example +$ @kbd{mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \ + -boot-load-size 4 -boot-info-table -o grub.iso iso} +@end example + +This produces a file named @file{grub.iso}, which then can be burned +into a CD (or a DVD). @kbd{mkisofs} has already set up the disc to boot +from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to +setup GRUB on the disc. (Note that the @kbd{-boot-load-size 4} bit is +required for compatibility with the BIOS on many older machines.) + +You can use the device @samp{(cd)} to access a CD-ROM in your +config file. This is not required; GRUB automatically sets the root device +to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to +@samp{(cd)} if you want to access other drives as well. + + +@node Booting +@chapter Booting + +GRUB can load Multiboot-compliant kernels in a consistent way, +but for some free operating systems you need to use some OS-specific +magic. + +@menu +* General boot methods:: How to boot OSes with GRUB generally +* OS-specific notes:: Notes on some operating systems +* Making your system robust:: How to make your system robust +@end menu + + +@node General boot methods +@section How to boot operating systems + +GRUB has two distinct boot methods. One of the two is to load an +operating system directly, and the other is to chain-load another boot +loader which then will load an operating system actually. Generally +speaking, the former is more desirable, because you don't need to +install or maintain other boot loaders and GRUB is flexible enough to +load an operating system from an arbitrary disk/partition. However, +the latter is sometimes required, since GRUB doesn't support all the +existing operating systems natively. + +@menu +* Loading an operating system directly:: +* Chain-loading:: +@end menu + + +@node Loading an operating system directly +@subsection How to boot an OS directly with GRUB + +Multiboot (@pxref{Top, Multiboot Specification, Motivation, multiboot, +The Multiboot Specification}) is the native format supported by GRUB. +For the sake of convenience, there is also support for Linux, FreeBSD, +NetBSD and OpenBSD. If you want to boot other operating systems, you +will have to chain-load them (@pxref{Chain-loading}). + +Generally, GRUB can boot any Multiboot-compliant OS in the following +steps: + +@enumerate +@item +Set GRUB's root device to the drive where the OS images are stored with +the command @command{root} (@pxref{root}). + +@item +Load the kernel image with the command @command{kernel} (@pxref{kernel}). + +@item +If you need modules, load them with the command @command{module} +(@pxref{module}) or @command{modulenounzip} (@pxref{modulenounzip}). + +@item +Run the command @command{boot} (@pxref{boot}). +@end enumerate + +Linux, FreeBSD, NetBSD and OpenBSD can be booted in a similar +manner. You load a kernel image with the command @command{kernel} and +then run the command @command{boot}. If the kernel requires some +parameters, just append the parameters to @command{kernel}, after the +file name of the kernel. Also, please refer to @ref{OS-specific notes}, +for information on your OS-specific issues. + + +@node Chain-loading +@subsection Load another boot loader to boot unsupported operating systems + +If you want to boot an unsupported operating system (e.g. Windows 95), +chain-load a boot loader for the operating system. Normally, the boot +loader is embedded in the @dfn{boot sector} of the partition on which +the operating system is installed. + +@enumerate +@item +Set GRUB's root device to the partition by the command +@command{rootnoverify} (@pxref{rootnoverify}): + +@example +grub> @kbd{rootnoverify (hd0,0)} +@end example + +@item +Set the @dfn{active} flag in the partition using the command +@command{makeactive}@footnote{This is not necessary for most of the +modern operating systems.} (@pxref{makeactive}): + +@example +grub> @kbd{makeactive} +@end example + +@item +Load the boot loader with the command @command{chainloader} +(@pxref{chainloader}): + +@example +grub> @kbd{chainloader +1} +@end example + +@samp{+1} indicates that GRUB should read one sector from the start of +the partition. The complete description about this syntax can be found +in @ref{Block list syntax}. + +@item +Run the command @command{boot} (@pxref{boot}). +@end enumerate + +However, DOS and Windows have some deficiencies, so you might have to +use more complicated instructions. @xref{DOS/Windows}, for more +information. + + +@node OS-specific notes +@section Some caveats on OS-specific issues + +Here, we describe some caveats on several operating systems. + +@menu +* GNU/Hurd:: +* GNU/Linux:: +* FreeBSD:: +* NetBSD:: +* OpenBSD:: +* DOS/Windows:: +* SCO UnixWare:: +* QNX:: +@end menu + + +@node GNU/Hurd +@subsection GNU/Hurd + +Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is +nothing special about it. But do not forget that you have to specify a +root partition to the kernel. + +@enumerate +@item +Set GRUB's root device to the same drive as GNU/Hurd's. Probably the +command @code{find /boot/gnumach} or similar can help you +(@pxref{find}). + +@item +Load the kernel and the module, like this: + +@example +@group +grub> @kbd{kernel /boot/gnumach root=hd0s1} +grub> @kbd{module /boot/serverboot} +@end group +@end example + +@item +Run the command @command{boot} (@pxref{boot}). +@end enumerate + + +@node GNU/Linux +@subsection GNU/Linux + +It is relatively easy to boot GNU/Linux from GRUB, because it somewhat +resembles to boot a Multiboot-compliant OS. + +@enumerate +@item +Set GRUB's root device to the same drive as GNU/Linux's. Probably the +command @code{find /vmlinuz} or similar can help you (@pxref{find}). + +@item +Load the kernel: + +@example +grub> @kbd{kernel /vmlinuz root=/dev/hda1} +@end example + +If you need to specify some kernel parameters, just append them to the +command. For example, to set @option{vga} to @samp{ext}, do this: + +@example +grub> @kbd{kernel /vmlinuz root=/dev/hda1 vga=ext} +@end example + +See the documentation in the Linux source tree for complete +information on the available options. + +@item +If you use an initrd, execute the command @command{initrd} +(@pxref{initrd}) after @command{kernel}: + +@example +grub> @kbd{initrd /initrd} +@end example + +@item +Finally, run the command @command{boot} (@pxref{boot}). +@end enumerate + +@strong{Caution:} If you use an initrd and specify the @samp{mem=} +option to the kernel to let it use less than actual memory size, you +will also have to specify the same memory size to GRUB. To let GRUB know +the size, run the command @command{uppermem} @emph{before} loading the +kernel. @xref{uppermem}, for more information. + + +@node FreeBSD +@subsection FreeBSD + +GRUB can load the kernel directly, either in ELF or a.out format. But +this is not recommended, since FreeBSD's bootstrap interface sometimes +changes heavily, so GRUB can't guarantee to pass kernel parameters +correctly. + +Thus, we'd recommend loading the very flexible loader +@file{/boot/loader} instead. See this example: + +@example +@group +grub> @kbd{root (hd0,a)} +grub> @kbd{kernel /boot/loader} +grub> @kbd{boot} +@end group +@end example + + +@node NetBSD +@subsection NetBSD + +GRUB can load NetBSD a.out and ELF directly, follow these steps: + +@enumerate +@item +Set GRUB's root device with @command{root} (@pxref{root}). + +@item +Load the kernel with @command{kernel} (@pxref{kernel}). You should +append the ugly option @option{--type=netbsd}, if you want to load an +ELF kernel, like this: + +@example +grub> @kbd{kernel --type=netbsd /netbsd-elf} +@end example + +@item +Run @command{boot} (@pxref{boot}). +@end enumerate + +For now, however, GRUB doesn't allow you to pass kernel parameters, so +it may be better to chain-load it instead. For more information, please +see @ref{Chain-loading}. + + +@node OpenBSD +@subsection OpenBSD + +The booting instruction is exactly the same as for NetBSD +(@pxref{NetBSD}). + + +@node DOS/Windows +@subsection DOS/Windows + +GRUB cannot boot DOS or Windows directly, so you must chain-load them +(@pxref{Chain-loading}). However, their boot loaders have some critical +deficiencies, so it may not work to just chain-load them. To overcome +the problems, GRUB provides you with two helper functions. + +If you have installed DOS (or Windows) on a non-first hard disk, you +have to use the disk swapping technique, because that OS cannot boot +from any disks but the first one. The workaround used in GRUB is the +command @command{map} (@pxref{map}), like this: + +@example +@group +grub> @kbd{map (hd0) (hd1)} +grub> @kbd{map (hd1) (hd0)} +@end group +@end example + +This performs a @dfn{virtual} swap between your first and second hard +drive. + +@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS +to access the swapped disks. If that OS uses a special driver for the +disks, this probably won't work. + +Another problem arises if you installed more than one set of DOS/Windows +onto one disk, because they could be confused if there are more than one +primary partitions for DOS/Windows. Certainly you should avoid doing +this, but there is a solution if you do want to do so. Use the partition +hiding/unhiding technique. + +If GRUB @dfn{hide}s a DOS (or Windows) partition (@pxref{hide}), DOS (or +Windows) will ignore the partition. If GRUB @dfn{unhide}s a DOS (or +Windows) partition (@pxref{unhide}), DOS (or Windows) will detect the +partition. Thus, if you have installed DOS (or Windows) on the first +and the second partition of the first hard disk, and you want to boot +the copy on the first partition, do the following: + +@example +@group +grub> @kbd{unhide (hd0,0)} +grub> @kbd{hide (hd0,1)} +grub> @kbd{rootnoverify (hd0,0)} +grub> @kbd{chainloader +1} +grub> @kbd{makeactive} +grub> @kbd{boot} +@end group +@end example + + +@node SCO UnixWare +@subsection SCO UnixWare + +It is known that the signature in the boot loader for SCO UnixWare is +wrong, so you will have to specify the option @option{--force} to +@command{chainloader} (@pxref{chainloader}), like this: + +@example +@group +grub> @kbd{rootnoverify (hd1,0)} +grub> @kbd{chainloader --force +1} +grub> @kbd{makeactive} +grub> @kbd{boot} +@end group +@end example + + +@node QNX +@subsection QNX + +QNX seems to use a bigger boot loader, so you need to boot it up, like +this: + +@example +@group +grub> @kbd{rootnoverify (hd1,1)} +grub> @kbd{chainloader +4} +grub> @kbd{boot} +@end group +@end example + + +@node Making your system robust +@section How to make your system robust + +When you test a new kernel or a new OS, it is important to make sure +that your computer can boot even if the new system is unbootable. This +is crucial especially if you maintain servers or remote systems. To +accomplish this goal, you need to set up two things: + +@enumerate +@item +You must maintain a system which is always bootable. For instance, if +you test a new kernel, you need to keep a working kernel in a +different place. And, it would sometimes be very nice to even have a +complete copy of a working system in a different partition or disk. + +@item +You must direct GRUB to boot a working system when the new system +fails. This is possible with the @dfn{fallback} system in GRUB. +@end enumerate + +The former requirement is very specific to each OS, so this +documentation does not cover that topic. It is better to consult some +backup tools. + +So let's see the GRUB part. There are two possibilities: one of them +is quite simple but not very robust, and the other is a bit complex to +set up but probably the best solution to make sure that your system +can start as long as GRUB itself is bootable. + +@menu +* Booting once-only:: +* Booting fallback systems:: +@end menu + + +@node Booting once-only +@subsection Booting once-only + +You can teach GRUB to boot an entry only at next boot time. Suppose +that your have an old kernel @file{old_kernel} and a new kernel +@file{new_kernel}. You know that @file{old_kernel} can boot +your system correctly, and you want to test @file{new_kernel}. + +To ensure that your system will go back to the old kernel even if the +new kernel fails (e.g. it panics), you can specify that GRUB should +try the new kernel only once and boot the old kernel after that. + +First, modify your configuration file. Here is an example: + +@example +@group +default saved # This is important!!! +timeout 10 + +title the old kernel +root (hd0,0) +kernel /old_kernel +savedefault + +title the new kernel +root (hd0,0) +kernel /new_kernel +savedefault 0 # This is important!!! +@end group +@end example + +Note that this configuration file uses @samp{default saved} +(@pxref{default}) at the head and @samp{savedefault 0} +(@pxref{savedefault}) in the entry for the new kernel. This means +that GRUB boots a saved entry by default, and booting the entry for the +new kernel saves @samp{0} as the saved entry. + +With this configuration file, after all, GRUB always tries to boot the +old kernel after it booted the new one, because @samp{0} is the entry +of @code{the old kernel}. + +The next step is to tell GRUB to boot the new kernel at next boot +time. For this, execute @command{grub-set-default} (@pxref{Invoking +grub-set-default}): + +@example +# @kbd{grub-set-default 1} +@end example + +This command sets the saved entry to @samp{1}, that is, to the new +kernel. + +This method is useful, but still not very robust, because GRUB stops +booting, if there is any error in the boot entry, such that the new +kernel has an invalid executable format. Thus, it it even better to +use the @dfn{fallback} mechanism of GRUB. Look at next subsection for +this feature. + + +@node Booting fallback systems +@subsection Booting fallback systems + +GRUB supports a fallback mechanism of booting one or more other +entries if a default boot entry fails. You can specify multiple +fallback entries if you wish. + +Suppose that you have three systems, @samp{A}, @samp{B} and +@samp{C}. @samp{A} is a system which you want to boot by +default. @samp{B} is a backup system which is supposed to boot +safely. @samp{C} is another backup system which is used in case where +@samp{B} is broken. + +Then you may want GRUB to boot the first system which is bootable +among @samp{A}, @samp{B} and @samp{C}. A configuration file can be +written in this way: + +@example +@group +default saved # This is important!!! +timeout 10 +fallback 1 2 # This is important!!! + +title A +root (hd0,0) +kernel /kernel +savedefault fallback # This is important!!! + +title B +root (hd1,0) +kernel /kernel +savedefault fallback # This is important!!! + +title C +root (hd2,0) +kernel /kernel +savedefault +@end group +@end example + +Note that @samp{default saved} (@pxref{default}), @samp{fallback 1 2} +and @samp{savedefault fallback} are used. GRUB will boot a saved entry +by default and save a fallback entry as next boot entry with this +configuration. + +When GRUB tries to boot @samp{A}, GRUB saves @samp{1} as next boot +entry, because the command @command{fallback} specifies that @samp{1} +is the first fallback entry. The entry @samp{1} is @samp{B}, so GRUB +will try to boot @samp{B} at next boot time. + +Likewise, when GRUB tries to boot @samp{B}, GRUB saves @samp{2} as +next boot entry, because @command{fallback} specifies @samp{2} as next +fallback entry. This makes sure that GRUB will boot @samp{C} after +booting @samp{B}. + +It is noteworthy that GRUB uses fallback entries both when GRUB +itself fails in booting an entry and when @samp{A} or @samp{B} fails +in starting up your system. So this solution ensures that your system +is started even if GRUB cannot find your kernel or if your kernel +panics. + +However, you need to run @command{grub-set-default} (@pxref{Invoking +grub-set-default}) when @samp{A} starts correctly or you fix @samp{A} +after it crashes, since GRUB always sets next boot entry to a fallback +entry. You should run this command in a startup script such as +@file{rc.local} to boot @samp{A} by default: + +@example +# @kbd{grub-set-default 0} +@end example + +where @samp{0} is the number of the boot entry for the system +@samp{A}. + +If you want to see what is current default entry, you can look at the +file @file{/boot/grub/default} (or @file{/grub/default} in +some systems). Because this file is plain-text, you can just +@command{cat} this file. But it is strongly recommended @strong{not to +modify this file directly}, because GRUB may fail in saving a default +entry in this file, if you change this file in an unintended +manner. Therefore, you should use @command{grub-set-default} when you +need to change the default entry. + + +@node Configuration +@chapter Configuration + +You've probably noticed that you need to type several commands to boot your +OS. There's a solution to that - GRUB provides a menu interface +(@pxref{Menu interface}) from which you can select an item (using arrow +keys) that will do everything to boot an OS. + +To enable the menu, you need a configuration file, +@file{menu.lst} under the boot directory. We'll analyze an example +file. + +The file first contains some general settings, the menu interface +related options. You can put these commands (@pxref{Menu-specific +commands}) before any of the items (starting with @command{title} +(@pxref{title})). + +@example +@group +# +# Sample boot menu configuration file +# +@end group +@end example + +As you may have guessed, these lines are comments. Lines starting with a +hash character (@samp{#}), and blank lines, are ignored by GRUB. + +@example +@group +# By default, boot the first entry. +default 0 +@end group +@end example + +The first entry (here, counting starts with number zero, not one!) will +be the default choice. + +@example +@group +# Boot automatically after 30 secs. +timeout 30 +@end group +@end example + +As the comment says, GRUB will boot automatically in 30 seconds, unless +interrupted with a keypress. + +@example +@group +# Fallback to the second entry. +fallback 1 +@end group +@end example + +If, for any reason, the default entry doesn't work, fall back to the +second one (this is rarely used, for obvious reasons). + +Note that the complete descriptions of these commands, which are menu +interface specific, can be found in @ref{Menu-specific +commands}. Other descriptions can be found in @ref{Commands}. + +Now, on to the actual OS definitions. You will see that each entry +begins with a special command, @command{title} (@pxref{title}), and the +action is described after it. Note that there is no command +@command{boot} (@pxref{boot}) at the end of each item. That is because +GRUB automatically executes @command{boot} if it loads other commands +successfully. + +The argument for the command @command{title} is used to display a short +title/description of the entry in the menu. Since @command{title} +displays the argument as is, you can write basically anything there. + +@example +@group +# For booting GNU/Hurd +title GNU/Hurd +root (hd0,0) +kernel /boot/gnumach.gz root=hd0s1 +module /boot/serverboot.gz +@end group +@end example + +This boots GNU/Hurd from the first hard disk. + +@example +@group +# For booting GNU/Linux +title GNU/Linux +kernel (hd1,0)/vmlinuz root=/dev/hdb1 +@end group +@end example + +This boots GNU/Linux, but from the second hard disk. + +@example +@group +# For booting Mach (getting kernel from floppy) +title Utah Mach4 multiboot +root (hd0,2) +pause Insert the diskette now^G!! +kernel (fd0)/boot/kernel root=hd0s3 +module (fd0)/boot/bootstrap +@end group +@end example + +This boots Mach with a kernel on a floppy, but the root filesystem at +hd0s3. It also contains a @command{pause} line (@pxref{pause}), which +will cause GRUB to display a prompt and delay, before actually executing +the rest of the commands and booting. + +@example +@group +# For booting FreeBSD +title FreeBSD +root (hd0,2,a) +kernel /boot/loader +@end group +@end example + +This item will boot FreeBSD kernel loaded from the @samp{a} partition of +the third @sc{pc} slice of the first hard disk. + +@example +@group +# For booting OS/2 +title OS/2 +root (hd0,1) +makeactive +# chainload OS/2 bootloader from the first sector +chainloader +1 +# This is similar to "chainload", but loads a specific file +#chainloader /boot/chain.os2 +@end group +@end example + +This will boot OS/2, using a chain-loader (@pxref{Chain-loading}). + +@example +@group +# For booting Windows NT or Windows95 +title Windows NT / Windows 95 boot menu +root (hd0,0) +makeactive +chainloader +1 +# For loading DOS if Windows NT is installed +# chainload /bootsect.dos +@end group +@end example + +The same as the above, but for Windows. + +@example +@group +# For installing GRUB into the hard disk +title Install GRUB into the hard disk +root (hd0,0) +setup (hd0) +@end group +@end example + +This will just (re)install GRUB onto the hard disk. + +@example +# Change the colors. +title Change the colors +color light-green/brown blink-red/blue +@end example + +In the last entry, the command @command{color} is used (@pxref{color}), +to change the menu colors (try it!). This command is somewhat special, +because it can be used both in the command-line and in the menu. GRUB +has several such commands, see @ref{General commands}. + +We hope that you now understand how to use the basic features of +GRUB. To learn more about GRUB, see the following chapters. + + +@node Network +@chapter Downloading OS images from a network + +Although GRUB is a disk-based boot loader, it does provide network +support. To use the network support, you need to enable at least one +network driver in the GRUB build process. For more information please +see @file{netboot/README.netboot} in the source distribution. + +@menu +* General usage of network support:: +* Diskless:: +@end menu + + +@node General usage of network support +@section How to set up your network + +GRUB requires a file server and optionally a server that will assign an +IP address to the machine on which GRUB is running. For the former, only +TFTP is supported at the moment. The latter is either BOOTP, DHCP or a +RARP server@footnote{RARP is not advised, since it cannot serve much +information}. It is not necessary to run both the servers on one +computer. How to configure these servers is beyond the scope of this +document, so please refer to the manuals specific to those +protocols/servers. + +If you decided to use a server to assign an IP address, set up the +server and run @command{bootp} (@pxref{bootp}), @command{dhcp} +(@pxref{dhcp}) or @command{rarp} (@pxref{rarp}) for BOOTP, DHCP or RARP, +respectively. Each command will show an assigned IP address, a netmask, +an IP address for your TFTP server and a gateway. If any of the +addresses is wrong or it causes an error, probably the configuration of +your servers isn't set up properly. + +Otherwise, run @command{ifconfig}, like this: + +@example +grub> @kbd{ifconfig --address=192.168.110.23 --server=192.168.110.14} +@end example + +You can also use @command{ifconfig} in conjuction with @command{bootp}, +@command{dhcp} or @command{rarp} (e.g. to reassign the server address +manually). @xref{ifconfig}, for more details. + +Finally, download your OS images from your network. The network can be +accessed using the network drive @samp{(nd)}. Everything else is very +similar to the normal instructions (@pxref{Booting}). + +Here is an example: + +@example +@group +grub> @kbd{bootp} +Probing... [NE*000] +NE2000 base ... +Address: 192.168.110.23 Netmask: 255.255.255.0 +Server: 192.168.110.14 Gateway: 192.168.110.1 + +grub> @kbd{root (nd)} +grub> @kbd{kernel /tftproot/gnumach.gz root=sd0s1} +grub> @kbd{module /tftproot/serverboot.gz} +grub> @kbd{boot} +@end group +@end example + + +@node Diskless +@section Booting from a network + +It is sometimes very useful to boot from a network, especially when you +use a machine which has no local disk. In this case, you need to obtain +a kind of Net Boot @sc{rom}, such as a PXE @sc{rom} or a free software +package like Etherboot. Such a Boot @sc{rom} first boots the machine, +sets up the network card installed into the machine, and downloads a +second stage boot image from the network. Then, the second image will +try to boot an operating system actually from the network. + +GRUB provides two second stage images, @file{nbgrub} and +@file{pxegrub} (@pxref{Images}). These images are the same as the +normal Stage 2, except that they set up a network automatically, and try +to load a configuration file from the network, if specified. The usage +is very simple: If the machine has a PXE @sc{rom}, use +@file{pxegrub}. If the machine has an NBI loader such as Etherboot, use +@file{nbgrub}. There is no difference between them except their +formats. Since the way to load a second stage image you want to use +should be described in the manual on your Net Boot @sc{rom}, please +refer to the manual, for more information. + +However, there is one thing specific to GRUB. Namely, how to specify a +configuration file in a BOOTP/DHCP server. For now, GRUB uses the tag +@samp{150}, to get the name of a configuration file. The following is an +example with a BOOTP configuration: + +@example +@group +.allhost:hd=/tmp:bf=null:\ + :ds=145.71.35.1 145.71.32.1:\ + :sm=255.255.254.0:\ + :gw=145.71.35.1:\ + :sa=145.71.35.5: + +foo:ht=1:ha=63655d0334a7:ip=145.71.35.127:\ + :bf=/nbgrub:\ + :tc=.allhost:\ + :T150="(nd)/tftpboot/menu.lst.foo": +@end group +@end example + +Note that you should specify the drive name @code{(nd)} in the name of +the configuration file. This is because you might change the root drive +before downloading the configuration from the TFTP server when the +preset menu feature is used (@pxref{Preset Menu}). + +See the manual of your BOOTP/DHCP server for more information. The +exact syntax should differ a little from the example. + + +@node Serial terminal +@chapter Using GRUB via a serial line + +This chapter describes how to use the serial terminal support in GRUB. + +If you have many computers or computers with no display/keyboard, it +could be very useful to control the computers through serial +communications. To connect one computer with another via a serial line, +you need to prepare a null-modem (cross) serial cable, and you may need +to have multiport serial boards, if your computer doesn't have extra +serial ports. In addition, a terminal emulator is also required, such as +minicom. Refer to a manual of your operating system, for more +information. + +As for GRUB, the instruction to set up a serial terminal is quite +simple. First of all, make sure that you haven't specified the option +@option{--disable-serial} to the configure script when you built your +GRUB images. If you get them in binary form, probably they have serial +terminal support already. + +Then, initialize your serial terminal after GRUB starts up. Here is an +example: + +@example +@group +grub> @kbd{serial --unit=0 --speed=9600} +grub> @kbd{terminal serial} +@end group +@end example + +The command @command{serial} initializes the serial unit 0 with the +speed 9600bps. The serial unit 0 is usually called @samp{COM1}, so, if +you want to use COM2, you must specify @samp{--unit=1} instead. This +command accepts many other options, so please refer to @ref{serial}, +for more details. + +The command @command{terminal} (@pxref{terminal}) chooses which type of +terminal you want to use. In the case above, the terminal will be a +serial terminal, but you can also pass @code{console} to the command, +as @samp{terminal serial console}. In this case, a terminal in which +you press any key will be selected as a GRUB terminal. + +However, note that GRUB assumes that your terminal emulator is +compatible with VT100 by default. This is true for most terminal +emulators nowadays, but you should pass the option @option{--dumb} to +the command if your terminal emulator is not VT100-compatible or +implements few VT100 escape sequences. If you specify this option then +GRUB provides you with an alternative menu interface, because the normal +menu requires several fancy features of your terminal. + + +@node Preset Menu +@chapter Embedding a configuration file into GRUB + +GRUB supports a @dfn{preset menu} which is to be always loaded before +starting. The preset menu feature is useful, for example, when your +computer has no console but a serial cable. In this case, it is +critical to set up the serial terminal as soon as possible, since you +cannot see any message until the serial terminal begins to work. So it +is good to run the commands @command{serial} (@pxref{serial}) and +@command{terminal} (@pxref{terminal}) before anything else at the +start-up time. + +How the preset menu works is slightly complicated: + +@enumerate +@item +GRUB checks if the preset menu feature is used, and loads the preset +menu, if available. This includes running commands and reading boot +entries, like an ordinary configuration file. + +@item +GRUB checks if the configuration file is available. Note that this check +is performed @strong{regardless of the existence of the preset +menu}. The configuration file is loaded even if the preset menu was +loaded. + +@item +If the preset menu includes any boot entries, they are cleared when +the configuration file is loaded. It doesn't matter whether the +configuration file has any entries or no entry. The boot entries in the +preset menu are used only when GRUB fails in loading the configuration +file. +@end enumerate + +To enable the preset menu feature, you must rebuild GRUB specifying a +file to the configure script with the option +@option{--enable-preset-menu}. The file has the same semantics as +normal configuration files (@pxref{Configuration}). + +Another point you should take care is that the diskless support +(@pxref{Diskless}) diverts the preset menu. Diskless images embed a +preset menu to execute the command @command{bootp} (@pxref{bootp}) +automatically, unless you specify your own preset menu to the configure +script. This means that you must put commands to initialize a network in +the preset menu yourself, because diskless images don't set it up +implicitly, when you use the preset menu explicitly. + +Therefore, a typical preset menu used with diskless support would be +like this: + +@example +@group +# Set up the serial terminal, first of all. +serial --unit=0 --speed=19200 +terminal --timeout=0 serial + +# Initialize the network. +dhcp +@end group +@end example + + +@node Security +@chapter Protecting your computer from cracking + +You may be interested in how to prevent ordinary users from doing +whatever they like, if you share your computer with other people. So +this chapter describes how to improve the security of GRUB. + +One thing which could be a security hole is that the user can do too +many things with GRUB, because GRUB allows one to modify its configuration +and run arbitrary commands at run-time. For example, the user can even +read @file{/etc/passwd} in the command-line interface by the command +@command{cat} (@pxref{cat}). So it is necessary to disable all the +interactive operations. + +Thus, GRUB provides a @dfn{password} feature, so that only administrators +can start the interactive operations (i.e. editing menu entries and +entering the command-line interface). To use this feature, you need to +run the command @command{password} in your configuration file +(@pxref{password}), like this: + +@example +password --md5 PASSWORD +@end example + +If this is specified, GRUB disallows any interactive control, until you +press the key @key{p} and enter a correct password. The option +@option{--md5} tells GRUB that @samp{PASSWORD} is in MD5 format. If it +is omitted, GRUB assumes the @samp{PASSWORD} is in clear text. + +You can encrypt your password with the command @command{md5crypt} +(@pxref{md5crypt}). For example, run the grub shell (@pxref{Invoking the +grub shell}), and enter your password: + +@example +@group +grub> md5crypt +Password: ********** +Encrypted: $1$U$JK7xFegdxWH6VuppCUSIb. +@end group +@end example + +Then, cut and paste the encrypted password to your configuration file. + +Also, you can specify an optional argument to @command{password}. See +this example: + +@example +password PASSWORD /boot/grub/menu-admin.lst +@end example + +In this case, GRUB will load @file{/boot/grub/menu-admin.lst} as a +configuration file when you enter the valid password. + +Another thing which may be dangerous is that any user can choose any +menu entry. Usually, this wouldn't be problematic, but you might want to +permit only administrators to run some of your menu entries, such as an +entry for booting an insecure OS like DOS. + +GRUB provides the command @command{lock} (@pxref{lock}). This command +always fails until you enter the valid password, so you can use it, like +this: + +@example +@group +title Boot DOS +lock +rootnoverify (hd0,1) +makeactive +chainload +1 +@end group +@end example + +You should insert @command{lock} right after @command{title}, because +any user can execute commands in an entry until GRUB encounters +@command{lock}. + +You can also use the command @command{password} instead of +@command{lock}. In this case the boot process will ask for the password +and stop if it was entered incorrectly. Since the @command{password} +takes its own @var{PASSWORD} argument this is useful if you want +different passwords for different entries. + + +@node Images +@chapter GRUB image files + +GRUB consists of several images: two essential stages, optional stages +called @dfn{Stage 1.5}, one image for bootable CD-ROM, and two network +boot images. Here is a short overview of them. @xref{Internals}, for +more details. + +@table @file +@item stage1 +This is an essential image used for booting up GRUB. Usually, this is +embedded in an MBR or the boot sector of a partition. Because a PC boot +sector is 512 bytes, the size of this image is exactly 512 bytes. + +All @file{stage1} must do is to load Stage 2 or Stage 1.5 from a local +disk. Because of the size restriction, @file{stage1} encodes the +location of Stage 2 (or Stage 1.5) in a block list format, so it never +understand any filesystem structure. + +@item stage2 +This is the core image of GRUB. It does everything but booting up +itself. Usually, this is put in a filesystem, but that is not required. + +@item e2fs_stage1_5 +@itemx fat_stage1_5 +@itemx ffs_stage1_5 +@itemx jfs_stage1_5 +@itemx minix_stage1_5 +@itemx reiserfs_stage1_5 +@itemx vstafs_stage1_5 +@itemx xfs_stage1_5 + +These are called @dfn{Stage 1.5}, because they serve as a bridge +between @file{stage1} and @file{stage2}, that is to say, Stage 1.5 is +loaded by Stage 1 and Stage 1.5 loads Stage 2. The difference between +@file{stage1} and @file{*_stage1_5} is that the former doesn't +understand any filesystem while the latter understands one filesystem +(e.g. @file{e2fs_stage1_5} understands ext2fs). So you can move the +Stage 2 image to another location safely, even after GRUB has been +installed. + +While Stage 2 cannot generally be embedded in a fixed area as the size +is so large, Stage 1.5 can be installed into the area right after an MBR, +or the boot loader area of a ReiserFS or a FFS. + +@item stage2_eltorito +This is a boot image for CD-ROMs using the @dfn{no emulation mode} in +El Torito specification. This is identical to Stage 2, except that +this boots up without Stage 1 and sets up a special drive @samp{(cd)}. + +@item nbgrub +This is a network boot image for the Network Image Proposal used by some +network boot loaders, such as Etherboot. This is mostly the same as +Stage 2, but it also sets up a network and loads a configuration file +from the network. + +@item pxegrub +This is another network boot image for the Preboot Execution Environment +used by several Netboot ROMs. This is identical to @file{nbgrub}, except +for the format. +@end table + + +@node Filesystem +@chapter Filesystem syntax and semantics + +GRUB uses a special syntax for specifying disk drives which can be +accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish +between IDE, ESDI, SCSI, or others. You must know yourself which BIOS +device is equivalent to which OS device. Normally, that will be clear if +you see the files in a device or use the command @command{find} +(@pxref{find}). + +@menu +* Device syntax:: How to specify devices +* File name syntax:: How to specify files +* Block list syntax:: How to specify block lists +@end menu + + +@node Device syntax +@section How to specify devices + +The device syntax is like this: + +@example +@code{(@var{device}[,@var{part-num}][,@var{bsd-subpart-letter}])} +@end example + +@samp{[]} means the parameter is optional. @var{device} should be +either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}. +But you can also set @var{device} to a hexadecimal or a decimal number +which is a BIOS drive number, so the following are equivalent: + +@example +(hd0) +(0x80) +(128) +@end example + +@var{part-num} represents the partition number of @var{device}, starting +from zero for primary partitions and from four for extended partitions, +and @var{bsd-subpart-letter} represents the BSD disklabel subpartition, +such as @samp{a} or @samp{e}. + +A shortcut for specifying BSD subpartitions is +@code{(@var{device},@var{bsd-subpart-letter})}, in this case, GRUB +searches for the first PC partition containing a BSD disklabel, then +finds the subpartition @var{bsd-subpart-letter}. Here is an example: + +@example +(hd0,a) +@end example + +The syntax @samp{(hd0)} represents using the entire disk (or the +MBR when installing GRUB), while the syntax @samp{(hd0,0)} +represents using the first partition of the disk (or the boot sector +of the partition when installing GRUB). + +If you enabled the network support, the special drive, @samp{(nd)}, is +also available. Before using the network drive, you must initialize the +network. @xref{Network}, for more information. + +If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making +a GRUB bootable CD-ROM}, for details. + + +@node File name syntax +@section How to specify files + +There are two ways to specify files, by @dfn{absolute file name} and by +@dfn{block list}. + +An absolute file name resembles a Unix absolute file name, using +@samp{/} for the directory separator (not @samp{\} as in DOS). One +example is @samp{(hd0,0)/boot/grub/menu.lst}. This means the file +@file{/boot/grub/menu.lst} in the first partition of the first hard +disk. If you omit the device name in an absolute file name, GRUB uses +GRUB's @dfn{root device} implicitly. So if you set the root device to, +say, @samp{(hd1,0)} by the command @command{root} (@pxref{root}), then +@code{/boot/kernel} is the same as @code{(hd1,0)/boot/kernel}. + + +@node Block list syntax +@section How to specify block lists + +A block list is used for specifying a file that doesn't appear in the +filesystem, like a chainloader. The syntax is +@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}. +Here is an example: + +@example +@code{0+100,200+1,300+300} +@end example + +This represents that GRUB should read blocks 0 through 99, block 200, +and blocks 300 through 599. If you omit an offset, then GRUB assumes +the offset is zero. + +Like the file name syntax (@pxref{File name syntax}), if a blocklist +does not contain a device name, then GRUB uses GRUB's @dfn{root +device}. So @code{(hd0,1)+1} is the same as @code{+1} when the root +device is @samp{(hd0,1)}. + + +@node Interface +@chapter GRUB's user interface + +GRUB has both a simple menu interface for choosing preset entries from a +configuration file, and a highly flexible command-line for performing +any desired combination of boot commands. + +GRUB looks for its configuration file as soon as it is loaded. If one +is found, then the full menu interface is activated using whatever +entries were found in the file. If you choose the @dfn{command-line} menu +option, or if the configuration file was not found, then GRUB drops to +the command-line interface. + +@menu +* Command-line interface:: The flexible command-line interface +* Menu interface:: The simple menu interface +* Menu entry editor:: Editing a menu entry +* Hidden menu interface:: The hidden menu interface +@end menu + + +@node Command-line interface +@section The flexible command-line interface + +The command-line interface provides a prompt and after it an editable +text area much like a command-line in Unix or DOS. Each command is +immediately executed after it is entered@footnote{However, this +behavior will be changed in the future version, in a user-invisible +way.}. The commands (@pxref{Command-line and menu entry commands}) are a +subset of those available in the configuration file, used with exactly +the same syntax. + +Cursor movement and editing of the text on the line can be done via a +subset of the functions available in the Bash shell: + +@table @key +@item C-f +@itemx PC right key +Move forward one character. + +@item C-b +@itemx PC left key +Move back one character. + +@item C-a +@itemx HOME +Move to the start of the line. + +@item C-e +@itemx END +Move the the end of the line. + +@item C-d +@itemx DEL +Delete the character underneath the cursor. + +@item C-h +@itemx BS +Delete the character to the left of the cursor. + +@item C-k +Kill the text from the current cursor position to the end of the line. + +@item C-u +Kill backward from the cursor to the beginning of the line. + +@item C-y +Yank the killed text back into the buffer at the cursor. + +@item C-p +@itemx PC up key +Move up through the history list. + +@item C-n +@itemx PC down key +Move down through the history list. +@end table + +When typing commands interactively, if the cursor is within or before +the first word in the command-line, pressing the @key{TAB} key (or +@key{C-i}) will display a listing of the available commands, and if the +cursor is after the first word, the @kbd{@key{TAB}} will provide a +completion listing of disks, partitions, and file names depending on the +context. Note that to obtain a list of drives, one must open a +parenthesis, as @command{root (}. + +Note that you cannot use the completion functionality in the TFTP +filesystem. This is because TFTP doesn't support file name listing for +the security. + + +@node Menu interface +@section The simple menu interface + +The menu interface is quite easy to use. Its commands are both +reasonably intuitive and described on screen. + +Basically, the menu interface provides a list of @dfn{boot entries} to +the user to choose from. Use the arrow keys to select the entry of +choice, then press @key{RET} to run it. An optional timeout is +available to boot the default entry (the first one if not set), which is +aborted by pressing any key. + +Commands are available to enter a bare command-line by pressing @key{c} +(which operates exactly like the non-config-file version of GRUB, but +allows one to return to the menu if desired by pressing @key{ESC}) or to +edit any of the @dfn{boot entries} by pressing @key{e}. + +If you protect the menu interface with a password (@pxref{Security}), +all you can do is choose an entry by pressing @key{RET}, or press +@key{p} to enter the password. + + +@node Menu entry editor +@section Editing a menu entry + +The menu entry editor looks much like the main menu interface, but the +lines in the menu are individual commands in the selected entry instead +of entry names. + +If an @key{ESC} is pressed in the editor, it aborts all the changes made +to the configuration entry and returns to the main menu interface. + +When a particular line is selected, the editor places the user in a +special version of the GRUB command-line to edit that line. When the +user hits @key{RET}, GRUB replaces the line in question in the boot +entry with the changes (unless it was aborted via @key{ESC}, +in which case the changes are thrown away). + +If you want to add a new line to the menu entry, press @key{o} if adding +a line after the current line or press @key{O} if before the current +line. + +To delete a line, hit the key @key{d}. Although GRUB unfortunately +does not support @dfn{undo}, you can do almost the same thing by just +returning to the main menu. + + +@node Hidden menu interface +@section The hidden menu interface + +When your terminal is dumb or you request GRUB to hide the menu +interface explicitly with the command @command{hiddenmenu} +(@pxref{hiddenmenu}), GRUB doesn't show the menu interface (@pxref{Menu +interface}) and automatically boots the default entry, unless +interrupted by pressing @key{ESC}. + +When you interrupt the timeout and your terminal is dumb, GRUB falls +back to the command-line interface (@pxref{Command-line interface}). + + +@node Commands +@chapter The list of available commands + +In this chapter, we list all commands that are available in GRUB. + +Commands belong to different groups. A few can only be used in +the global section of the configuration file (or ``menu''); most +of them can be entered on the command-line and can be used either +anywhere in the menu or specifically in the menu entries. + +@menu +* Menu-specific commands:: +* General commands:: +* Command-line and menu entry commands:: +@end menu + + +@node Menu-specific commands +@section The list of commands for the menu only + +The semantics used in parsing the configuration file are the following: + +@itemize @bullet +@item +The menu-specific commands have to be used before any others. + +@item +The files @emph{must} be in plain-text format. + +@item +@samp{#} at the beginning of a line in a configuration file means it is +only a comment. + +@item +Options are separated by spaces. + +@item +All numbers can be either decimal or hexadecimal. A hexadecimal number +must be preceded by @samp{0x}, and is case-insensitive. + +@item +Extra options or text at the end of the line are ignored unless otherwise +specified. + +@item +Unrecognized commands are added to the current entry, except before entries +start, where they are ignored. +@end itemize + +These commands can only be used in the menu: + +@menu +* default:: Set the default entry +* fallback:: Set the fallback entry +* hiddenmenu:: Hide the menu interface +* timeout:: Set the timeout +* title:: Start a menu entry +@end menu + + +@node default +@subsection default + +@deffn Command default num +Set the default entry to the entry number @var{num}. Numbering starts +from 0, and the entry number 0 is the default if the command is not +used. + +You can specify @samp{saved} instead of a number. In this case, the +default entry is the entry saved with the command +@command{savedefault}. @xref{savedefault}, for more information. +@end deffn + + +@node fallback +@subsection fallback + +@deffn Command fallback num... +Go into unattended boot mode: if the default boot entry has any errors, +instead of waiting for the user to do something, immediately start +over using the @var{num} entry (same numbering as the @code{default} +command (@pxref{default})). This obviously won't help if the machine was +rebooted by a kernel that GRUB loaded. You can specify multiple +fallback entry numbers. +@end deffn + + +@node hiddenmenu +@subsection hiddenmenu + +@deffn Command hiddenmenu +Don't display the menu. If the command is used, no menu will be +displayed on the control terminal, and the default entry will be +booted after the timeout expired. The user can still request the +menu to be displayed by pressing @key{ESC} before the timeout +expires. See also @ref{Hidden menu interface}. +@end deffn + + +@node timeout +@subsection timeout + +@deffn Command timeout sec +Set a timeout, in @var{sec} seconds, before automatically booting the +default entry (normally the first entry defined). +@end deffn + + +@node title +@subsection title + +@deffn Command title name @dots{} +Start a new boot entry, and set its name to the contents of the rest of +the line, starting with the first non-space character. +@end deffn + + +@node General commands +@section The list of general commands + +Commands usable anywhere in the menu and in the command-line. + +@menu +* bootp:: Initialize a network device via BOOTP +* color:: Color the menu interface +* device:: Specify a file as a drive +* dhcp:: Initialize a network device via DHCP +* hide:: Hide a partition +* ifconfig:: Configure a network device manually +* pager:: Change the state of the internal pager +* partnew:: Make a primary partition +* parttype:: Change the type of a partition +* password:: Set a password for the menu interface +* rarp:: Initialize a network device via RARP +* serial:: Set up a serial device +* setkey:: Configure the key map +* terminal:: Choose a terminal +* terminfo:: Define escape sequences for a terminal +* tftpserver:: Specify a TFTP server +* unhide:: Unhide a partition +@end menu + + +@node bootp +@subsection bootp + +@deffn Command bootp [@option{--with-configfile}] +Initialize a network device via the @dfn{BOOTP} protocol. This command +is only available if GRUB is compiled with netboot support. See also +@ref{Network}. + +If you specify @option{--with-configfile} to this command, GRUB will +fetch and load a configuration file specified by your BOOTP server +with the vendor tag @samp{150}. +@end deffn + + +@node color +@subsection color + +@deffn Command color normal [highlight] +Change the menu colors. The color @var{normal} is used for most +lines in the menu (@pxref{Menu interface}), and the color +@var{highlight} is used to highlight the line where the cursor +points. If you omit @var{highlight}, then the inverted color of +@var{normal} is used for the highlighted line. The format of a color is +@code{@var{foreground}/@var{background}}. @var{foreground} and +@var{background} are symbolic color names. A symbolic color name must be +one of these: + +@itemize @bullet +@item +black + +@item +blue + +@item +green + +@item +cyan + +@item +red + +@item +magenta + +@item +brown + +@item +light-gray + +@strong{These below can be specified only for the foreground.} + +@item +dark-gray + +@item +light-blue + +@item +light-green + +@item +light-cyan + +@item +light-red + +@item +light-magenta + +@item +yellow + +@item +white +@end itemize + +But only the first eight names can be used for @var{background}. You can +prefix @code{blink-} to @var{foreground} if you want a blinking +foreground color. + +This command can be used in the configuration file and on the command +line, so you may write something like this in your configuration file: + +@example +@group +# Set default colors. +color light-gray/blue black/light-gray + +# Change the colors. +title OS-BS like +color magenta/blue black/magenta +@end group +@end example +@end deffn + + +@node device +@subsection device + +@deffn Command device drive file +In the grub shell, specify the file @var{file} as the actual drive for a +@sc{bios} drive @var{drive}. You can use this command to create a disk +image, and/or to fix the drives guessed by GRUB when GRUB fails to +determine them correctly, like this: + +@example +@group +grub> @kbd{device (fd0) /floppy-image} +grub> @kbd{device (hd0) /dev/sd0} +@end group +@end example + +This command can be used only in the grub shell (@pxref{Invoking the +grub shell}). +@end deffn + + +@node dhcp +@subsection dhcp + +@deffn Command dhcp [--with-configfile] +Initialize a network device via the @dfn{DHCP} protocol. Currently, +this command is just an alias for @command{bootp}, since the two +protocols are very similar. This command is only available if GRUB is +compiled with netboot support. See also @ref{Network}. + +If you specify @option{--with-configfile} to this command, GRUB will +fetch and load a configuration file specified by your DHCP server +with the vendor tag @samp{150}. +@end deffn + + +@node hide +@subsection hide + +@deffn Command hide partition +Hide the partition @var{partition} by setting the @dfn{hidden} bit in +its partition type code. This is useful only when booting DOS or Windows +and multiple primary FAT partitions exist in one disk. See also +@ref{DOS/Windows}. +@end deffn + + +@node ifconfig +@subsection ifconfig + +@deffn Command ifconfig [@option{--server=server}] [@option{--gateway=gateway}] [@option{--mask=mask}] [@option{--address=address}] +Configure the IP address, the netmask, the gateway, and the server +address of a network device manually. The values must be in dotted +decimal format, like @samp{192.168.11.178}. The order of the options is +not important. This command shows current network configuration, if no +option is specified. See also @ref{Network}. +@end deffn + + +@node pager +@subsection pager + +@deffn Command pager [flag] +Toggle or set the state of the internal pager. If @var{flag} is +@samp{on}, the internal pager is enabled. If @var{flag} is @samp{off}, +it is disabled. If no argument is given, the state is toggled. +@end deffn + + +@node partnew +@subsection partnew + +@deffn Command partnew part type from len +Create a new primary partition. @var{part} is a partition specification +in GRUB syntax (@pxref{Naming convention}); @var{type} is the partition +type and must be a number in the range @code{0-0xff}; @var{from} is +the starting address and @var{len} is the length, both in sector units. +@end deffn + + +@node parttype +@subsection parttype + +@deffn Command parttype part type +Change the type of an existing partition. @var{part} is a partition +specification in GRUB syntax (@pxref{Naming convention}); @var{type} +is the new partition type and must be a number in the range 0-0xff. +@end deffn + + +@node password +@subsection password + +@deffn Command password [@option{--md5}] passwd [new-config-file] +If used in the first section of a menu file, disable all interactive +editing control (menu entry editor and command-line) and entries +protected by the command @command{lock}. If the password @var{passwd} is +entered, it loads the @var{new-config-file} as a new config file and +restarts the GRUB Stage 2, if @var{new-config-file} is +specified. Otherwise, GRUB will just unlock the privileged instructions. +You can also use this command in the script section, in which case it +will ask for the password, before continuing. The option +@option{--md5} tells GRUB that @var{passwd} is encrypted with +@command{md5crypt} (@pxref{md5crypt}). +@end deffn + + +@node rarp +@subsection rarp + +@deffn Command rarp +Initialize a network device via the @dfn{RARP} protocol. This command +is only available if GRUB is compiled with netboot support. See also +@ref{Network}. +@end deffn + + +@node serial +@subsection serial + +@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}] +Initialize a serial device. @var{unit} is a number in the range 0-3 +specifying which serial port to use; default is 0, which corresponds to +the port often called COM1. @var{port} is the I/O port where the UART +is to be found; if specified it takes precedence over @var{unit}. +@var{speed} is the transmission speed; default is 9600. @var{word} and +@var{stop} are the number of data bits and stop bits. Data bits must +be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data +bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, +@samp{even} and defaults to @samp{no}. The option @option{--device} +can only be used in the grub shell and is used to specify the +tty device to be used in the host operating system (@pxref{Invoking the +grub shell}). + +The serial port is not used as a communication channel unless the +@command{terminal} command is used (@pxref{terminal}). + +This command is only available if GRUB is compiled with serial +support. See also @ref{Serial terminal}. +@end deffn + + +@node setkey +@subsection setkey + +@deffn Command setkey [to_key from_key] +Change the keyboard map. The key @var{from_key} is mapped to the key +@var{to_key}. If no argument is specified, reset key mappings. Note that +this command @emph{does not} exchange the keys. If you want to exchange +the keys, run this command again with the arguments exchanged, like this: + +@example +grub> @kbd{setkey capslock control} +grub> @kbd{setkey control capslock} +@end example + +A key must be an alphabet letter, a digit, or one of these symbols: +@samp{escape}, @samp{exclam}, @samp{at}, @samp{numbersign}, +@samp{dollar}, @samp{percent}, @samp{caret}, @samp{ampersand}, +@samp{asterisk}, @samp{parenleft}, @samp{parenright}, @samp{minus}, +@samp{underscore}, @samp{equal}, @samp{plus}, @samp{backspace}, +@samp{tab}, @samp{bracketleft}, @samp{braceleft}, @samp{bracketright}, +@samp{braceright}, @samp{enter}, @samp{control}, @samp{semicolon}, +@samp{colon}, @samp{quote}, @samp{doublequote}, @samp{backquote}, +@samp{tilde}, @samp{shift}, @samp{backslash}, @samp{bar}, @samp{comma}, +@samp{less}, @samp{period}, @samp{greater}, @samp{slash}, +@samp{question}, @samp{alt}, @samp{space}, @samp{capslock}, @samp{FX} +(@samp{X} is a digit), and @samp{delete}. This table describes to which +character each of the symbols corresponds: + +@table @samp +@item exclam +@samp{!} + +@item at +@samp{@@} + +@item numbersign +@samp{#} + +@item dollar +@samp{$} + +@item percent +@samp{%} + +@item caret +@samp{^} + +@item ampersand +@samp{&} + +@item asterisk +@samp{*} + +@item parenleft +@samp{(} + +@item parenright +@samp{)} + +@item minus +@samp{-} + +@item underscore +@samp{_} + +@item equal +@samp{=} + +@item plus +@samp{+} + +@item bracketleft +@samp{[} + +@item braceleft +@samp{@{} + +@item bracketright +@samp{]} + +@item braceright +@samp{@}} + +@item semicolon +@samp{;} + +@item colon +@samp{:} + +@item quote +@samp{'} + +@item doublequote +@samp{"} + +@item backquote +@samp{`} + +@item tilde +@samp{~} + +@item backslash +@samp{\} + +@item bar +@samp{|} + +@item comma +@samp{,} + +@item less +@samp{<} + +@item period +@samp{.} + +@item greater +@samp{>} + +@item slash +@samp{/} + +@item question +@samp{?} + +@item space +@samp{ } +@end table +@end deffn + + +@node terminal +@subsection terminal + +@deffn Command terminal [@option{--dumb}] [@option{--no-echo}] [@option{--no-edit}] [@option{--timeout=secs}] [@option{--lines=lines}] [@option{--silent}] [@option{console}] [@option{serial}] [@option{hercules}] +Select a terminal for user interaction. The terminal is assumed to be +VT100-compatible unless @option{--dumb} is specified. If both +@option{console} and @option{serial} are specified, then GRUB will use +the one where a key is entered first or the first when the timeout +expires. If neither are specified, the current setting is +reported. This command is only available if GRUB is compiled with serial +support. See also @ref{Serial terminal}. + +This may not make sense for most users, but GRUB supports Hercules +console as well. Hercules console is usable like the ordinary console, +and the usage is quite similar to that for serial terminals: specify +@option{hercules} as the argument. + +The option @option{--lines} defines the number of lines in your +terminal, and it is used for the internal pager function. If you don't +specify this option, the number is assumed as 24. + +The option @option{--silent} suppresses the message to prompt you to +hit any key. This might be useful if your system has no terminal +device. + +The option @option{--no-echo} has GRUB not to echo back input +characters. This implies the option @option{--no-edit}. + +The option @option{--no-edit} disables the BASH-like editing feature. +@end deffn + + +@node terminfo +@subsection terminfo + +@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}] +Define the capabilities of your terminal. Use this command to define +escape sequences, if it is not vt100-compatible. You may use @samp{\e} +for @key{ESC} and @samp{^X} for a control character. + +You can use the utility @command{grub-terminfo} to generate +appropriate arguments to this command. @xref{Invoking grub-terminfo}. + +If no option is specified, the current settings are printed. +@end deffn + + +@node tftpserver +@subsection tftpserver + +@deffn Command tftpserver ipaddr +@strong{Caution:} This command exists only for backward +compatibility. Use @command{ifconfig} (@pxref{ifconfig}) instead. + +Override a TFTP server address returned by a BOOTP/DHCP/RARP server. The +argument @var{ipaddr} must be in dotted decimal format, like +@samp{192.168.0.15}. This command is only available if GRUB is compiled +with netboot support. See also @ref{Network}. +@end deffn + + +@node unhide +@subsection unhide + +@deffn Command unhide partition +Unhide the partition @var{partition} by clearing the @dfn{hidden} bit in +its partition type code. This is useful only when booting DOS or Windows +and multiple primary partitions exist on one disk. See also +@ref{DOS/Windows}. +@end deffn + + +@node Command-line and menu entry commands +@section The list of command-line and menu entry commands + +These commands are usable in the command-line and in menu entries. If +you forget a command, you can run the command @command{help} +(@pxref{help}). + +@menu +* blocklist:: Get the block list notation of a file +* boot:: Start up your operating system +* cat:: Show the contents of a file +* chainloader:: Chain-load another boot loader +* cmp:: Compare two files +* configfile:: Load a configuration file +* debug:: Toggle the debug flag +* displayapm:: Display APM information +* displaymem:: Display memory configuration +* embed:: Embed Stage 1.5 +* find:: Find a file +* fstest:: Test a filesystem +* geometry:: Manipulate the geometry of a drive +* halt:: Shut down your computer +* help:: Show help messages +* impsprobe:: Probe SMP +* initrd:: Load an initrd +* install:: Install GRUB +* ioprobe:: Probe I/O ports used for a drive +* kernel:: Load a kernel +* lock:: Lock a menu entry +* makeactive:: Make a partition active +* map:: Map a drive to another +* md5crypt:: Encrypt a password in MD5 format +* module:: Load a module +* modulenounzip:: Load a module without decompression +* pause:: Wait for a key press +* quit:: Exit from the grub shell +* reboot:: Reboot your computer +* read:: Read data from memory +* root:: Set GRUB's root device +* rootnoverify:: Set GRUB's root device without mounting +* savedefault:: Save current entry as the default entry +* setup:: Set up GRUB's installation automatically +* testload:: Load a file for testing a filesystem +* testvbe:: Test VESA BIOS EXTENSION +* uppermem:: Set the upper memory size +* vbeprobe:: Probe VESA BIOS EXTENSION +@end menu + + +@node blocklist +@subsection blocklist + +@deffn Command blocklist file +Print the block list notation of the file @var{file}. @xref{Block list +syntax}. +@end deffn + + +@node boot +@subsection boot + +@deffn Command boot +Boot the OS or chain-loader which has been loaded. Only necessary if +running the fully interactive command-line (it is implicit at the end of +a menu entry). +@end deffn + + +@node cat +@subsection cat + +@deffn Command cat file +Display the contents of the file @var{file}. This command may be useful +to remind you of your OS's root partition: + +@example +grub> @kbd{cat /etc/fstab} +@end example +@end deffn + + +@node chainloader +@subsection chainloader + +@deffn Command chainloader [@option{--force}] file +Load @var{file} as a chain-loader. Like any other file loaded by the +filesystem code, it can use the blocklist notation to grab the first +sector of the current partition with @samp{+1}. If you specify the +option @option{--force}, then load @var{file} forcibly, whether it has a +correct signature or not. This is required when you want to load a +defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}). +@end deffn + + +@node cmp +@subsection cmp + +@deffn Command cmp file1 file2 +Compare the file @var{file1} with the file @var{file2}. If they differ +in size, print the sizes like this: + +@example +Differ in size: 0x1234 [foo], 0x4321 [bar] +@end example + +If the sizes are equal but the bytes at an offset differ, then print the +bytes like this: + +@example +Differ at the offset 777: 0xbe [foo], 0xef [bar] +@end example + +If they are completely identical, nothing will be printed. +@end deffn + + +@node configfile +@subsection configfile + +@deffn Command configfile file +Load @var{file} as a configuration file. +@end deffn + + +@node debug +@subsection debug + +@deffn Command debug +Toggle debug mode (by default it is off). When debug mode is on, some +extra messages are printed to show disk activity. This global debug flag +is mainly useful for GRUB developers when testing new code. +@end deffn + + +@node displayapm +@subsection displayapm + +@deffn Command displayapm +Display APM BIOS information. +@end deffn + + +@node displaymem +@subsection displaymem + +@deffn Command displaymem +Display what GRUB thinks the system address space map of the machine is, +including all regions of physical @sc{ram} installed. GRUB's +@dfn{upper/lower memory} display uses the standard BIOS interface for +the available memory in the first megabyte, or @dfn{lower memory}, and a +synthesized number from various BIOS interfaces of the memory starting +at 1MB and going up to the first chipset hole for @dfn{upper memory} +(the standard PC @dfn{upper memory} interface is limited to reporting a +maximum of 64MB). +@end deffn + + +@node embed +@subsection embed + +@deffn Command embed stage1_5 device +Embed the Stage 1.5 @var{stage1_5} in the sectors after the MBR if +@var{device} is a drive, or in the @dfn{boot loader} area if @var{device} +is a FFS partition or a ReiserFS partition.@footnote{The latter feature +has not been implemented yet.} Print the number of sectors which +@var{stage1_5} occupies, if successful. + +Usually, you don't need to run this command directly. @xref{setup}. +@end deffn + + +@node find +@subsection find + +@deffn Command find filename +Search for the file name @var{filename} in all mountable partitions +and print the list of the devices which contain the file. The file +name @var{filename} should be an absolute file name like +@code{/boot/grub/stage1}. +@end deffn + + +@node fstest +@subsection fstest + +@deffn Command fstest +Toggle filesystem test mode. +Filesystem test mode, when turned on, prints out data corresponding to +all the device reads and what values are being sent to the low-level +routines. The format is @samp{<@var{partition-offset-sector}, +@var{byte-offset}, @var{byte-length}>} for high-level reads inside a +partition, and @samp{[@var{disk-offset-sector}]} for low-level sector +requests from the disk. +Filesystem test mode is turned off by any use of the @command{install} +(@pxref{install}) or @command{testload} (@pxref{testload}) commands. +@end deffn + + +@node geometry +@subsection geometry + +@deffn Command geometry drive [cylinder head sector [total_sector]] +Print the information for the drive @var{drive}. In the grub shell, you +can set the geometry of the drive arbitrarily. The number of +cylinders, the number of heads, the number of sectors and the number of +total sectors are set to CYLINDER, HEAD, SECTOR and TOTAL_SECTOR, +respectively. If you omit TOTAL_SECTOR, then it will be calculated +based on the C/H/S values automatically. +@end deffn + + +@node halt +@subsection halt + +@deffn Command halt @option{--no-apm} +The command halts the computer. If the @option{--no-apm} option +is specified, no APM BIOS call is performed. Otherwise, the computer +is shut down using APM. +@end deffn + + +@node help +@subsection help + +@deffn Command help @option{--all} [pattern @dots{}] +Display helpful information about builtin commands. If you do not +specify @var{pattern}, this command shows short descriptions of most of +available commands. If you specify the option @option{--all} to this +command, short descriptions of rarely used commands (such as +@ref{testload}) are displayed as well. + +If you specify any @var{patterns}, it displays longer information +about each of the commands which match those @var{patterns}. +@end deffn + + +@node impsprobe +@subsection impsprobe + +@deffn Command impsprobe +Probe the Intel Multiprocessor Specification 1.1 or 1.4 configuration +table and boot the various CPUs which are found into a tight loop. This +command can be used only in the Stage 2, but not in the grub shell. +@end deffn + + +@node initrd +@subsection initrd + +@deffn Command initrd file @dots{} +Load an initial ramdisk for a Linux format boot image and set the +appropriate parameters in the Linux setup area in memory. See also +@ref{GNU/Linux}. +@end deffn + + +@node install +@subsection install + +@deffn Command install [@option{--force-lba}] [@option{--stage2=os_stage2_file}] stage1_file [@option{d}] dest_dev stage2_file [addr] [@option{p}] [config_file] [real_config_file] +This command is fairly complex, and you should not use this command +unless you are familiar with GRUB. Use @command{setup} (@pxref{setup}) +instead. + +In short, it will perform a full install presuming the Stage 2 or Stage +1.5@footnote{They're loaded the same way, so we will refer to the Stage +1.5 as a Stage 2 from now on.} is in its final install location. + +In slightly more detail, it will load @var{stage1_file}, validate that +it is a GRUB Stage 1 of the right version number, install in it a +blocklist for loading @var{stage2_file} as a Stage 2. If the option +@option{d} is present, the Stage 1 will always look for the actual +disk @var{stage2_file} was installed on, rather than using the booting +drive. The Stage 2 will be loaded at address @var{addr}, which must be +@samp{0x8000} for a true Stage 2, and @samp{0x2000} for a Stage 1.5. If +@var{addr} is not present, GRUB will determine the address +automatically. It then writes the completed Stage 1 to the first block +of the device @var{dest_dev}. If the options @option{p} or +@var{config_file} are present, then it reads the first block of stage2, +modifies it with the values of the partition @var{stage2_file} was found +on (for @option{p}) or places the string @var{config_file} into the area +telling the stage2 where to look for a configuration file at boot +time. Likewise, if @var{real_config_file} is present and +@var{stage2_file} is a Stage 1.5, then the Stage 2 @var{config_file} is +patched with the configuration file name @var{real_config_file}. This +command preserves the DOS BPB (and for hard disks, the partition table) +of the sector the Stage 1 is to be installed into. + +@strong{Caution:} Several buggy BIOSes don't pass a booting drive +properly when booting from a hard disk drive. Therefore, you will +unfortunately have to specify the option @option{d}, whether your +Stage2 resides at the booting drive or not, if you have such a +BIOS. We know these are defective in this way: + +@table @asis +@item +Fujitsu LifeBook 400 BIOS version 31J0103A + +@item +HP Vectra XU 6/200 BIOS version GG.06.11 +@end table + +@strong{Caution2:} A number of BIOSes don't return a correct LBA support +bitmap even if they do have the support. So GRUB provides a solution to +ignore the wrong bitmap, that is, the option @option{--force-lba}. Don't +use this option if you know that your BIOS doesn't have LBA support. + +@strong{Caution3:} You must specify the option @option{--stage2} in the +grub shell, if you cannot unmount the filesystem where your stage2 file +resides. The argument should be the file name in your operating system. +@end deffn + + +@node ioprobe +@subsection ioprobe + +@deffn Command ioprobe drive +Probe I/O ports used for the drive @var{drive}. This command will list +the I/O ports on the screen. For technical information, +@xref{Internals}. +@end deffn + + +@node kernel +@subsection kernel + +@deffn Command kernel [@option{--type=type}] [@option{--no-mem-option}] file @dots{} +Attempt to load the primary boot image (Multiboot a.out or @sc{elf}, +Linux zImage or bzImage, FreeBSD a.out, NetBSD a.out, etc.) from +@var{file}. The rest of the line is passed verbatim as the @dfn{kernel +command-line}. Any modules must be reloaded after using this command. + +This command also accepts the option @option{--type} so that you can +specify the kernel type of @var{file} explicitly. The argument +@var{type} must be one of these: @samp{netbsd}, @samp{freebsd}, +@samp{openbsd}, @samp{linux}, @samp{biglinux}, and +@samp{multiboot}. However, you need to specify it only if you want to +load a NetBSD @sc{elf} kernel, because GRUB can automatically determine +a kernel type in the other cases, quite safely. + +The option @option{--no-mem-option} is effective only for Linux. If the +option is specified, GRUB doesn't pass the option @option{mem=} to the +kernel. This option is implied for Linux kernels 2.4.18 and newer. +@end deffn + + +@node lock +@subsection lock + +@deffn Command lock +Prevent normal users from executing arbitrary menu entries. You must use +the command @command{password} if you really want this command to be +useful (@pxref{password}). + +This command is used in a menu, as shown in this example: + +@example +@group +title This entry is too dangerous to be executed by normal users +lock +root (hd0,a) +kernel /no-security-os +@end group +@end example + +See also @ref{Security}. +@end deffn + + +@node makeactive +@subsection makeactive + +@deffn Command makeactive +Set the active partition on the root disk to GRUB's root device. +This command is limited to @emph{primary} PC partitions on a hard disk. +@end deffn + + +@node map +@subsection map + +@deffn Command map to_drive from_drive +Map the drive @var{from_drive} to the drive @var{to_drive}. This is +necessary when you chain-load some operating systems, such as DOS, if +such an OS resides at a non-first drive. Here is an example: + +@example +@group +grub> @kbd{map (hd0) (hd1)} +grub> @kbd{map (hd1) (hd0)} +@end group +@end example + +The example exchanges the order between the first hard disk and the +second hard disk. See also @ref{DOS/Windows}. +@end deffn + + +@node md5crypt +@subsection md5crypt + +@deffn Command md5crypt +Prompt to enter a password, and encrypt it in MD5 format. The encrypted +password can be used with the command @command{password} +(@pxref{password}). See also @ref{Security}. +@end deffn + + +@node module +@subsection module + +@deffn Command module file @dots{} +Load a boot module @var{file} for a Multiboot format boot image (no +interpretation of the file contents are made, so the user of this +command must know what the kernel in question expects). The rest of the +line is passed as the @dfn{module command-line}, like the +@command{kernel} command. You must load a Multiboot kernel image before +loading any module. See also @ref{modulenounzip}. +@end deffn + + +@node modulenounzip +@subsection modulenounzip + +@deffn Command modulenounzip file @dots{} +The same as @command{module} (@pxref{module}), except that automatic +decompression is disabled. +@end deffn + + +@node pause +@subsection pause + +@deffn Command pause message @dots{} +Print the @var{message}, then wait until a key is pressed. Note that +placing @key{^G} (ASCII code 7) in the message will cause the speaker to +emit the standard beep sound, which is useful when prompting the user to +change floppies. +@end deffn + + +@node quit +@subsection quit + +@deffn Command quit +Exit from the grub shell @command{grub} (@pxref{Invoking the grub +shell}). This command can be used only in the grub shell. +@end deffn + + +@node reboot +@subsection reboot + +@deffn Command reboot +Reboot the computer. +@end deffn + + +@node read +@subsection read + +@deffn Command read addr +Read a 32-bit value from memory at address @var{addr} and display it in +hex format. +@end deffn + + +@node root +@subsection root + +@deffn Command root device [hdbias] +Set the current @dfn{root device} to the device @var{device}, then +attempt to mount it to get the partition size (for passing the partition +descriptor in @code{ES:ESI}, used by some chain-loaded boot loaders), the +BSD drive-type (for booting BSD kernels using their native boot format), +and correctly determine the PC partition where a BSD sub-partition is +located. The optional @var{hdbias} parameter is a number to tell a BSD +kernel how many BIOS drive numbers are on controllers before the current +one. For example, if there is an IDE disk and a SCSI disk, and your +FreeBSD root partition is on the SCSI disk, then use a @samp{1} for +@var{hdbias}. + +See also @ref{rootnoverify}. +@end deffn + + +@node rootnoverify +@subsection rootnoverify + +@deffn Command rootnoverify device [hdbias] +Similar to @command{root} (@pxref{root}), but don't attempt to mount the +partition. This is useful for when an OS is outside of the area of the +disk that GRUB can read, but setting the correct root device is still +desired. Note that the items mentioned in @command{root} above which +derived from attempting the mount will @emph{not} work correctly. +@end deffn + + +@node savedefault +@subsection savedefault + +@deffn Command savedefault num +Save the current menu entry or @var{num} if specified as a default +entry. Here is an example: + +@example +@group +default saved +timeout 10 + +title GNU/Linux +root (hd0,0) +kernel /boot/vmlinuz root=/dev/sda1 vga=ext +initrd /boot/initrd +savedefault + +title FreeBSD +root (hd0,a) +kernel /boot/loader +savedefault +@end group +@end example + +With this configuration, GRUB will choose the entry booted previously as +the default entry. + +You can specify @samp{fallback} instead of a number. Then, next +fallback entry is saved. Next fallback entry is chosen from fallback +entries. Normally, this will be the first entry in fallback ones. + +See also @ref{default} and @ref{Invoking grub-set-default}. +@end deffn + + +@node setup +@subsection setup + +@deffn Command setup [@option{--force-lba}] [@option{--stage2=os_stage2_file}] [@option{--prefix=dir}] install_device [image_device] +Set up the installation of GRUB automatically. This command uses the +more flexible command @command{install} (@pxref{install}) in the backend +and installs GRUB into the device @var{install_device}. If +@var{image_device} is specified, then find the GRUB images +(@pxref{Images}) in the device @var{image_device}, otherwise use the +current @dfn{root device}, which can be set by the command +@command{root}. If @var{install_device} is a hard disk, then embed a +Stage 1.5 in the disk if possible. + +The option @option{--prefix} specifies the directory under which GRUB +images are put. If it is not specified, GRUB automatically searches them +in @file{/boot/grub} and @file{/grub}. + +The options @option{--force-lba} and @option{--stage2} are just passed +to @command{install} if specified. @xref{install}, for more +information. +@end deffn + + +@node testload +@subsection testload + +@deffn Command testload file +Read the entire contents of @var{file} in several different ways and +compare them, to test the filesystem code. The output is somewhat +cryptic, but if no errors are reported and the final @samp{i=@var{X}, +filepos=@var{Y}} reading has @var{X} and @var{Y} equal, then it is +definitely consistent, and very likely works correctly subject to a +consistent offset error. If this test succeeds, then a good next step is +to try loading a kernel. +@end deffn + + +@node testvbe +@subsection testvbe + +@deffn Command testvbe mode +Test the VESA BIOS EXTENSION mode @var{mode}. This command will switch +your video card to the graphics mode, and show an endless animation. Hit +any key to return. See also @ref{vbeprobe}. +@end deffn + + +@node uppermem +@subsection uppermem + +@deffn Command uppermem kbytes +Force GRUB to assume that only @var{kbytes} kilobytes of upper memory +are installed. Any system address range maps are discarded. + +@strong{Caution:} This should be used with great caution, and should +only be necessary on some old machines. GRUB's BIOS probe can pick up +all @sc{ram} on all new machines the author has ever heard of. It can +also be used for debugging purposes to lie to an OS. +@end deffn + + +@node vbeprobe +@subsection vbeprobe + +@deffn Command vbeprobe [mode] +Probe VESA BIOS EXTENSION information. If the mode @var{mode} is +specified, show only the information about @var{mode}. Otherwise, this +command lists up available VBE modes on the screen. See also +@ref{testvbe}. +@end deffn + + +@node Troubleshooting +@chapter Error messages reported by GRUB + +This chapter describes error messages reported by GRUB when you +encounter trouble. @xref{Invoking the grub shell}, if your problem is +specific to the grub shell. + +@menu +* Stage1 errors:: Errors reported by the Stage 1 +* Stage1.5 errors:: Errors reported by the Stage 1.5 +* Stage2 errors:: Errors reported by the Stage 2 +@end menu + + +@node Stage1 errors +@section Errors reported by the Stage 1 + +The general way that the Stage 1 handles errors is to print an error +string and then halt. Pressing @kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will +reboot. + +The following is a comprehensive list of error messages for the Stage 1: + +@table @asis +@item Hard Disk Error +The stage2 or stage1.5 is being read from a hard disk, and the attempt +to determine the size and geometry of the hard disk failed. + +@item Floppy Error +The stage2 or stage1.5 is being read from a floppy disk, and the attempt +to determine the size and geometry of the floppy disk failed. It's listed +as a separate error since the probe sequence is different than for hard +disks. + +@item Read Error +A disk read error happened while trying to read the stage2 or stage1.5. + +@item Geom Error +The location of the stage2 or stage1.5 is not in the portion of the disk +supported directly by the BIOS read calls. This could occur because the +BIOS translated geometry has been changed by the user or the disk is +moved to another machine or controller after installation, or GRUB was +not installed using itself (if it was, the Stage 2 version of this error +would have been seen during that process and it would not have completed +the install). +@end table + + +@node Stage1.5 errors +@section Errors reported by the Stage 1.5 + +The general way that the Stage 1.5 handles errors is to print an error +number in the form @code{Error @var{num}} and then halt. Pressing +@kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will reboot. + +The error numbers correspond to the errors reported by Stage +2. @xref{Stage2 errors}. + + +@node Stage2 errors +@section Errors reported by the Stage 2 + +The general way that the Stage 2 handles errors is to abort the +operation in question, print an error string, then (if possible) either +continue based on the fact that an error occurred or wait for the user to +deal with the error. + +The following is a comprehensive list of error messages for the Stage 2 +(error numbers for the Stage 1.5 are listed before the colon in each +description): + +@table @asis +@item 1 : Filename must be either an absolute filename or blocklist +This error is returned if a file name is requested which doesn't fit the +syntax/rules listed in the @ref{Filesystem}. + +@item 2 : Bad file or directory type +This error is returned if a file requested is not a regular file, but +something like a symbolic link, directory, or FIFO. + +@item 3 : Bad or corrupt data while decompressing file +This error is returned if the run-length decompression code gets an +internal error. This is usually from a corrupt file. + +@item 4 : Bad or incompatible header in compressed file +This error is returned if the file header for a supposedly compressed +file is bad. + +@item 5 : Partition table invalid or corrupt +This error is returned if the sanity checks on the integrity of the +partition table fail. This is a bad sign. + +@item 6 : Mismatched or corrupt version of stage1/stage2 +This error is returned if the install command points to incompatible +or corrupt versions of the stage1 or stage2. It can't detect corruption +in general, but this is a sanity check on the version numbers, which +should be correct. + +@item 7 : Loading below 1MB is not supported +This error is returned if the lowest address in a kernel is below the +1MB boundary. The Linux zImage format is a special case and can be +handled since it has a fixed loading address and maximum size. + +@item 8 : Kernel must be loaded before booting +This error is returned if GRUB is told to execute the boot sequence +without having a kernel to start. + +@item 9 : Unknown boot failure +This error is returned if the boot attempt did not succeed for reasons +which are unknown. + +@item 10 : Unsupported Multiboot features requested +This error is returned when the Multiboot features word in the Multiboot +header requires a feature that is not recognized. The point of this is +that the kernel requires special handling which GRUB is probably +unable to provide. + +@item 11 : Unrecognized device string +This error is returned if a device string was expected, and the string +encountered didn't fit the syntax/rules listed in the @ref{Filesystem}. + +@item 12 : Invalid device requested +This error is returned if a device string is recognizable but does not +fall under the other device errors. + +@item 13 : Invalid or unsupported executable format +This error is returned if the kernel image being loaded is not +recognized as Multiboot or one of the supported native formats (Linux +zImage or bzImage, FreeBSD, or NetBSD). + +@item 14 : Filesystem compatibility error, cannot read whole file +Some of the filesystem reading code in GRUB has limits on the length of +the files it can read. This error is returned when the user runs into +such a limit. + +@item 15 : File not found +This error is returned if the specified file name cannot be found, but +everything else (like the disk/partition info) is OK. + +@item 16 : Inconsistent filesystem structure +This error is returned by the filesystem code to denote an internal +error caused by the sanity checks of the filesystem structure on disk +not matching what it expects. This is usually caused by a corrupt +filesystem or bugs in the code handling it in GRUB. + +@item 17 : Cannot mount selected partition +This error is returned if the partition requested exists, but the +filesystem type cannot be recognized by GRUB. + +@item 18 : Selected cylinder exceeds maximum supported by BIOS +This error is returned when a read is attempted at a linear block +address beyond the end of the BIOS translated area. This generally +happens if your disk is larger than the BIOS can handle (512MB for +(E)IDE disks on older machines or larger than 8GB in general). + +@item 19 : Linux kernel must be loaded before initrd +This error is returned if the initrd command is used before loading a +Linux kernel. + +@item 20 : Multiboot kernel must be loaded before modules +This error is returned if the module load command is used before loading +a Multiboot kernel. It only makes sense in this case anyway, as GRUB has +no idea how to communicate the presence of such modules to a +non-Multiboot-aware kernel. + +@item 21 : Selected disk does not exist +This error is returned if the device part of a device- or full file name +refers to a disk or BIOS device that is not present or not recognized by +the BIOS in the system. + +@item 22 : No such partition +This error is returned if a partition is requested in the device part of +a device- or full file name which isn't on the selected disk. + +@item 23 : Error while parsing number +This error is returned if GRUB was expecting to read a number and +encountered bad data. + +@item 24 : Attempt to access block outside partition +This error is returned if a linear block address is outside of the disk +partition. This generally happens because of a corrupt filesystem on the +disk or a bug in the code handling it in GRUB (it's a great debugging +tool). + +@item 25 : Disk read error +This error is returned if there is a disk read error when trying to +probe or read data from a particular disk. + +@item 26 : Too many symbolic links +This error is returned if the link count is beyond the maximum +(currently 5), possibly the symbolic links are looped. + +@item 27 : Unrecognized command +This error is returned if an unrecognized command is entered on the +command-line or in a boot sequence section of a configuration file and +that entry is selected. + +@item 28 : Selected item cannot fit into memory +This error is returned if a kernel, module, or raw file load command is +either trying to load its data such that it won't fit into memory or it +is simply too big. + +@item 29 : Disk write error +This error is returned if there is a disk write error when trying to +write to a particular disk. This would generally only occur during an +install of set active partition command. + +@item 30 : Invalid argument +This error is returned if an argument specified to a command is invalid. + +@item 31 : File is not sector aligned +This error may occur only when you access a ReiserFS partition by +block-lists (e.g. the command @command{install}). In this case, you +should mount the partition with the @samp{-o notail} option. + +@item 32 : Must be authenticated +This error is returned if you try to run a locked entry. You should +enter a correct password before running such an entry. + +@item 33 : Serial device not configured +This error is returned if you try to change your terminal to a serial +one before initializing any serial device. + +@item 34 : No spare sectors on the disk +This error is returned if a disk doesn't have enough spare space. This +happens when you try to embed Stage 1.5 into the unused sectors after +the MBR, but the first partition starts right after the MBR or they are +used by EZ-BIOS. +@end table + + +@node Invoking the grub shell +@chapter Invoking the grub shell + +This chapter documents the grub shell @command{grub}. Note that the grub +shell is an emulator; it doesn't run under the native environment, so it +sometimes does something wrong. Therefore, you shouldn't trust it too +much. If there is anything wrong with it, don't hesitate to try the +native GRUB environment, especially when it guesses a wrong map between +BIOS drives and OS devices. + +@menu +* Basic usage:: How to use the grub shell +* Installation under UNIX:: How to install GRUB via @command{grub} +* Device map:: The map between BIOS drives and OS devices +@end menu + + +@node Basic usage +@section Introduction into the grub shell + +You can use the command @command{grub} for installing GRUB under your +operating systems and for a testbed when you add a new feature into GRUB +or when fixing a bug. @command{grub} is almost the same as the Stage 2, +and, in fact, it shares the source code with the Stage 2 and you can use +the same commands (@pxref{Commands}) in @command{grub}. It is emulated by +replacing BIOS calls with UNIX system calls and libc functions. + +The command @command{grub} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item --verbose +Print some verbose messages for debugging purpose. + +@item --device-map=@var{file} +Use the device map file @var{file}. The format is described in +@ref{Device map}. + +@item --no-floppy +Do not probe any floppy drive. This option has no effect if the option +@option{--device-map} is specified (@pxref{Device map}). + +@item --probe-second-floppy +Probe the second floppy drive. If this option is not specified, the grub +shell does not probe it, as that sometimes takes a long time. If you +specify the device map file (@pxref{Device map}), the grub shell just +ignores this option. + +@item --config-file=@var{file} +Read the configuration file @var{file} instead of +@file{/boot/grub/menu.lst}. The format is the same as the normal GRUB +syntax. See @ref{Filesystem}, for more information. + +@item --boot-drive=@var{drive} +Set the stage2 @var{boot_drive} to @var{drive}. This argument should be +an integer (decimal, octal or hexadecimal). + +@item --install-partition=@var{par} +Set the stage2 @var{install_partition} to @var{par}. This argument +should be an integer (decimal, octal or hexadecimal). + +@item --no-config-file +Do not use the configuration file even if it can be read. + +@item --no-curses +Do not use the screen handling interface by the curses even if it is +available. + +@item --batch +This option has the same meaning as @samp{--no-config-file --no-curses}. + +@item --read-only +Disable writing to any disk. + +@item --hold +Wait until a debugger will attach. This option is useful when you want +to debug the startup code. +@end table + + +@node Installation under UNIX +@section How to install GRUB via @command{grub} + +The installation procedure is the same as under the @dfn{native} Stage +2. @xref{Installation}, for more information. The command +@command{grub}-specific information is described here. + +What you should be careful about is @dfn{buffer cache}. @command{grub} +makes use of raw devices instead of filesystems that your operating +systems serve, so there exists a potential problem that some cache +inconsistency may corrupt your filesystems. What we recommend is: + +@itemize @bullet +@item +If you can unmount drives to which GRUB may write any amount of data, +unmount them before running @command{grub}. + +@item +If a drive cannot be unmounted but can be mounted with the read-only +flag, mount it in read-only mode. That should be secure. + +@item +If a drive must be mounted with the read-write flag, make sure that no +activity is being done on it while the command @command{grub} is +running. + +@item +Reboot your operating system as soon as possible. This is probably not +required if you follow the rules above, but reboot is the most secure +way. +@end itemize + +In addition, enter the command @command{quit} when you finish the +installation. That is @emph{very important} because @command{quit} makes +the buffer cache consistent. Do not push @key{C-c}. + +If you want to install GRUB non-interactively, specify @samp{--batch} +option in the command-line. This is a simple example: + +@example +@group +#!/bin/sh + +# Use /usr/sbin/grub if you are on an older system. +/sbin/grub --batch </dev/null 2>/dev/null +root (hd0,0) +setup (hd0) +quit +EOT +@end group +@end example + + +@node Device map +@section The map between BIOS drives and OS devices + +When you specify the option @option{--device-map} (@pxref{Basic usage}), +the grub shell creates the @dfn{device map file} automatically unless it +already exists. The file name @file{/boot/grub/device.map} is preferred. + +If the device map file exists, the grub shell reads it to map BIOS +drives to OS devices. This file consists of lines like this: + +@example +@var{device} @var{file} +@end example + +@var{device} is a drive specified in the GRUB syntax (@pxref{Device +syntax}), and @var{file} is an OS file, which is normally a device +file. + +The reason why the grub shell gives you the device map file is that it +cannot guess the map between BIOS drives and OS devices correctly in +some environments. For example, if you exchange the boot sequence +between IDE and SCSI in your BIOS, it gets the order wrong. + +Thus, edit the file if the grub shell makes a mistake. You can put any +comments in the file if needed, as the grub shell assumes that a line is +just a comment if the first character is @samp{#}. + + +@node Invoking grub-install +@chapter Invoking grub-install + +The program @command{grub-install} installs GRUB on your drive using the +grub shell (@pxref{Invoking the grub shell}). You must specify the +device name on which you want to install GRUB, like this: + +@example +grub-install @var{install_device} +@end example + +The device name @var{install_device} is an OS device name or a GRUB +device name. + +@command{grub-install} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item --force-lba +Force GRUB to use LBA mode even for a buggy BIOS. Use this option only +if your BIOS doesn't work properly in LBA mode even though it supports +LBA mode. + +@item --root-directory=@var{dir} +Install GRUB images under the directory @var{dir} instead of the root +directory. This option is useful when you want to install GRUB into a +separate partition or a removable disk. Here is an example in which +you have a separate @dfn{boot} partition which is mounted on +@file{/boot}: + +@example +@kbd{grub-install --root-directory=/boot hd0} +@end example + +@item --grub-shell=@var{file} +Use @var{file} as the grub shell. You can append arbitrary options to +@var{file} after the file name, like this: + +@example +@kbd{grub-install --grub-shell="grub --read-only" /dev/fd0} +@end example + +@item --recheck +Recheck the device map, even if @file{/boot/grub/device.map} already +exists. You should use this option whenever you add/remove a disk +into/from your computer. +@end table + + +@node Invoking grub-md5-crypt +@chapter Invoking grub-md5-crypt + +The program @command{grub-md5-crypt} encrypts a password in MD5 format. +This is just a frontend of the grub shell (@pxref{Invoking the grub +shell}). Passwords encrypted by this program can be used with the +command @command{password} (@pxref{password}). + +@command{grub-md5-crypt} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version information and exit. + +@item --grub-shell=@var{file} +Use @var{file} as the grub shell. +@end table + + +@node Invoking grub-terminfo +@chapter Invoking grub-terminfo + +The program @command{grub-terminfo} generates a terminfo command from +a terminfo name (@pxref{terminfo}). The result can be used in the +configuration file, to define escape sequences. Because GRUB assumes +that your terminal is vt100-compatible by default, this would be +useful only if your terminal is uncommon (such as vt52). + +@command{grub-terminfo} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version information and exit. +@end table + +You must specify one argument to this command. For example: + +@example +@kbd{grub-terminfo vt52} +@end example + + +@node Invoking grub-set-default +@chapter Invoking grub-set-default + +The program @command{grub-set-default} sets the default boot entry for +GRUB. This automatically creates a file named @file{default} under +your GRUB directory (i.e. @file{/boot/grub}), if it is not +present. This file is used to determine the default boot entry when +GRUB boots up your system when you use @samp{default saved} in your +configuration file (@pxref{default}), and to save next default boot +entry when you use @samp{savedefault} in a boot entry +(@pxref{savedefault}). + +@command{grub-set-default} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version information and exit. + +@item --root-directory=@var{dir} +Use the directory @var{dir} instead of the root directory +(i.e. @file{/}) to define the location of the default file. This +is useful when you mount a disk which is used for another system. +@end table + +You must specify a single argument to @command{grub-set-default}. This +argument is normally the number of a default boot entry. For example, +if you have this configuration file: + +@example +@group +default saved +timeout 10 + +title GNU/Hurd +root (hd0,0) +... + +title GNU/Linux +root (hd0,1) +... +@end group +@end example + +and if you want to set the next default boot entry to GNU/Linux, you +may execute this command: + +@example +@kbd{grub-set-default 1} +@end example + +Because the entry for GNU/Linux is @samp{1}. Note that entries are +counted from zero. So, if you want to specify GNU/Hurd here, then you +should specify @samp{0}. + +This feature is very useful if you want to test a new kernel or to +make your system quite robust. @xref{Making your system robust}, for +more hints about how to set up a robust system. + + +@node Invoking mbchk +@chapter Invoking mbchk + +The program @command{mbchk} checks for the format of a Multiboot +kernel. We recommend using this program before booting your own kernel +by GRUB. + +@command{mbchk} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item --quiet +Suppress all normal output. +@end table + + +@node Obtaining and Building GRUB +@appendix How to obtain and build GRUB + +@quotation +@strong{Caution:} GRUB requires binutils-2.9.1.0.23 or later because the +GNU assembler has been changed so that it can produce real 16bits +machine code between 2.9.1 and 2.9.1.0.x. See +@uref{http://sources.redhat.com/binutils/}, to obtain information on +how to get the latest version. +@end quotation + +GRUB is available from the GNU alpha archive site +@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file +will be named grub-version.tar.gz. The current version is +@value{VERSION}, so the file you should grab is: + +@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz} + +To unbundle GRUB use the instruction: + +@example +@kbd{zcat grub-@value{VERSION}.tar.gz | tar xvf -} +@end example + +which will create a directory called @file{grub-@value{VERSION}} with +all the sources. You can look at the file @file{INSTALL} for detailed +instructions on how to build and install GRUB, but you should be able to +just do: + +@example +@group +@kbd{cd grub-@value{VERSION}} +@kbd{./configure} +@kbd{make install} +@end group +@end example + +This will install the grub shell @file{grub} (@pxref{Invoking the grub +shell}), the Multiboot checker @file{mbchk} (@pxref{Invoking mbchk}), +and the GRUB images. This will also install the GRUB manual. + +Also, the latest version is available from the CVS. See +@uref{http://savannah.gnu.org/cvs/?group=grub} for more information. + + +@node Reporting bugs +@appendix Reporting bugs + +These are the guideline for how to report bugs. Take a look at this +list below before you submit bugs: + +@enumerate +@item +Before getting unsettled, read this manual through and through. Also, +see the @uref{http://www.gnu.org/software/grub/grub-faq.html, GNU GRUB FAQ}. + +@item +Always mention the information on your GRUB. The version number and the +configuration are quite important. If you build it yourself, write the +options specified to the configure script and your operating system, +including the versions of gcc and binutils. + +@item +If you have trouble with the installation, inform us of how you +installed GRUB. Don't omit error messages, if any. Just @samp{GRUB hangs +up when it boots} is not enough. + +The information on your hardware is also essential. These are especially +important: the geometries and the partition tables of your hard disk +drives and your BIOS. + +@item +If GRUB cannot boot your operating system, write down +@emph{everything} you see on the screen. Don't paraphrase them, like +@samp{The foo OS crashes with GRUB, even though it can boot with the +bar boot loader just fine}. Mention the commands you executed, the +messages printed by them, and information on your operating system +including the version number. + +@item +Explain what you wanted to do. It is very useful to know your purpose +and your wish, and how GRUB didn't satisfy you. + +@item +If you can investigate the problem yourself, please do. That will give +you and us much more information on the problem. Attaching a patch is +even better. + +When you attach a patch, make the patch in unified diff format, and +write ChangeLog entries. But, even when you make a patch, don't forget +to explain the problem, so that we can understand what your patch is +for. + +@item +Write down anything that you think might be related. Please understand +that we often need to reproduce the same problem you encounterred in our +environment. So your information should be sufficient for us to do the +same thing---Don't forget that we cannot see your computer directly. If +you are not sure whether to state a fact or leave it out, state it! +Reporting too many things is much better than omitting something +important. +@end enumerate + +If you follow the guideline above, submit a report to the +@uref{http://savannah.gnu.org/bugs/?group=grub, Bug Tracking System}. +Alternatively, you can submit a report via electronic mail to +@email{bug-grub@@gnu.org}, but we strongly recommend that you use the +Bug Tracking System, because e-mail can be passed over easily. + +Once we get your report, we will try to fix the bugs. + + +@node Future +@appendix Where GRUB will go + +We started the next generation of GRUB, GRUB 2. This will include +internationalization, dynamic module loading, real memory management, +multiple architecture support, a scripting language, and many other +nice feature. If you are interested in the development of GRUB 2, take +a look at @uref{http://www.gnu.org/software/grub/grub.html, the +homepage}. + + + +@node Copying This Manual +@appendix Copying This Manual + +@menu +* GNU Free Documentation License:: License for copying this manual. +@end menu + +@include fdl.texi + + +@node Index +@unnumbered Index + +@c Currently, we use only the Concept Index. +@printindex cp + + +@bye + +Some notes: + + This is an attempt to make a manual for GRUB 2. The contents are + copied from the GRUB manual in GRUB Legacy, so they are not always + appropriate yet for GRUB 2. diff --git a/docs/mdate-sh b/docs/mdate-sh new file mode 100755 index 0000000..22f2f8b --- /dev/null +++ b/docs/mdate-sh @@ -0,0 +1,205 @@ +#!/bin/sh +# Get modification time of a file or directory and pretty-print it. + +scriptversion=2007-03-30.02 + +# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005, 2007 Free Software +# Foundation, Inc. +# written by Ulrich Drepper , June 1995 +# +# 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; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No file. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: mdate-sh [--help] [--version] FILE + +Pretty-print the modification time of FILE. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "mdate-sh $scriptversion" + exit $? + ;; +esac + +# Prevent date giving response in another language. +LANG=C +export LANG +LC_ALL=C +export LC_ALL +LC_TIME=C +export LC_TIME + +# GNU ls changes its time format in response to the TIME_STYLE +# variable. Since we cannot assume `unset' works, revert this +# variable to its documented default. +if test "${TIME_STYLE+set}" = set; then + TIME_STYLE=posix-long-iso + export TIME_STYLE +fi + +save_arg1=$1 + +# Find out how to get the extended ls output of a file or directory. +if ls -L /dev/null 1>/dev/null 2>&1; then + ls_command='ls -L -l -d' +else + ls_command='ls -l -d' +fi +# Avoid user/group names that might have spaces, when possible. +if ls -n /dev/null 1>/dev/null 2>&1; then + ls_command="$ls_command -n" +fi + +# A `ls -l' line looks as follows on OS/2. +# drwxrwx--- 0 Aug 11 2001 foo +# This differs from Unix, which adds ownership information. +# drwxrwx--- 2 root root 4096 Aug 11 2001 foo +# +# To find the date, we split the line on spaces and iterate on words +# until we find a month. This cannot work with files whose owner is a +# user named `Jan', or `Feb', etc. However, it's unlikely that `/' +# will be owned by a user whose name is a month. So we first look at +# the extended ls output of the root directory to decide how many +# words should be skipped to get the date. + +# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. +set x`$ls_command /` + +# Find which argument is the month. +month= +command= +until test $month +do + shift + # Add another shift to the command. + command="$command shift;" + case $1 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; + esac +done + +# Get the extended ls output of the file or directory. +set dummy x`eval "$ls_command \"\$save_arg1\""` + +# Remove all preceding arguments +eval $command + +# Because of the dummy argument above, month is in $2. +# +# On a POSIX system, we should have +# +# $# = 5 +# $1 = file size +# $2 = month +# $3 = day +# $4 = year or time +# $5 = filename +# +# On Darwin 7.7.0 and 7.6.0, we have +# +# $# = 4 +# $1 = day +# $2 = month +# $3 = year or time +# $4 = filename + +# Get the month. +case $2 in + Jan) month=January; nummonth=1;; + Feb) month=February; nummonth=2;; + Mar) month=March; nummonth=3;; + Apr) month=April; nummonth=4;; + May) month=May; nummonth=5;; + Jun) month=June; nummonth=6;; + Jul) month=July; nummonth=7;; + Aug) month=August; nummonth=8;; + Sep) month=September; nummonth=9;; + Oct) month=October; nummonth=10;; + Nov) month=November; nummonth=11;; + Dec) month=December; nummonth=12;; +esac + +case $3 in + ???*) day=$1;; + *) day=$3; shift;; +esac + +# Here we have to deal with the problem that the ls output gives either +# the time of day or the year. +case $3 in + *:*) set `date`; eval year=\$$# + case $2 in + Jan) nummonthtod=1;; + Feb) nummonthtod=2;; + Mar) nummonthtod=3;; + Apr) nummonthtod=4;; + May) nummonthtod=5;; + Jun) nummonthtod=6;; + Jul) nummonthtod=7;; + Aug) nummonthtod=8;; + Sep) nummonthtod=9;; + Oct) nummonthtod=10;; + Nov) nummonthtod=11;; + Dec) nummonthtod=12;; + esac + # For the first six month of the year the time notation can also + # be used for files modified in the last year. + if (expr $nummonth \> $nummonthtod) > /dev/null; + then + year=`expr $year - 1` + fi;; + *) year=$3;; +esac + +# The result. +echo $day $month $year + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/docs/texinfo.tex b/docs/texinfo.tex new file mode 100644 index 0000000..c49e670 --- /dev/null +++ b/docs/texinfo.tex @@ -0,0 +1,8959 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2007-09-03.05} +% +% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 2007, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007 Free Software Foundation, Inc. +% +% This texinfo.tex file 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, either version 3 of the +% License, or (at your option) any later version. +% +% This texinfo.tex file is distributed in the hope that it will be +% useful, but WITHOUT ANY WARRANTY; without even the implied warranty +% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +% General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. (This has been our intent since Texinfo was invented.) +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or +% ftp://tug.org/tex/texinfo.tex +% (and all CTAN mirrors, see http://www.ctan.org). +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexstar=\* +\let\ptext=\t + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% Use TeX 3.0's \inputlineno to get the line number, for better error +% messages, but if we're using an old version of TeX, don't do anything. +% +\ifx\inputlineno\thisisundefined + \let\linenumber = \empty % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Since the category of space is not known, we have to be careful. +\chardef\spacecat = 10 +\def\spaceisspace{\catcode`\ =\spacecat} + +% sometimes characters are active, so we need control sequences. +\chardef\colonChar = `\: +\chardef\commaChar = `\, +\chardef\dashChar = `\- +\chardef\dotChar = `\. +\chardef\exclamChar= `\! +\chardef\lquoteChar= `\` +\chardef\questChar = `\? +\chardef\rquoteChar= `\' +\chardef\semiChar = `\; +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\pagewidth \newdimen\pageheight + +% For a final copy, take out the rectangles +% that mark overfull boxes (in case you have decided +% that the text looks ok even though it passes the margin). +% +\def\finalout{\overfullrule=0pt} + +% @| inserts a changebar to the left of the current line. It should +% surround any changed text. This approach does *not* work if the +% change spans more than two lines of output. To handle that, we would +% have adopt a much more difficult approach (putting marks into the main +% vertical list for the beginning and end of each change). +% +\def\|{% + % \vadjust can only be used in horizontal mode. + \leavevmode + % + % Append this vertical mode material after the current line in the output. + \vadjust{% + % We want to insert a rule with the height and depth of the current + % leading; that is exactly what \strutbox is supposed to record. + \vskip-\baselineskip + % + % \vadjust-items are inserted at the left edge of the type. So + % the \llap here moves out into the left-hand margin. + \llap{% + % + % For a thicker or thinner bar, change the `1pt'. + \vrule height\baselineskip width1pt + % + % This is the space between the bar and the text. + \hskip 12pt + }% + }% +} + +% Sometimes it is convenient to have everything in the transcript file +% and nothing on the terminal. We don't just call \tracingall here, +% since that produces some useless output on the terminal. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\undefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% For @cropmarks command. +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. The solution is +% described on page 260 of The TeXbook. It involves outputting two +% marks for the sectioning macros, one before the section break, and +% one after. I won't pretend I can describe this better than DEK... +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 + \noexpand\or \the\toks4 \the\toks6 + \noexpand\else \the\toks8 + }% +} +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Main output routine. +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. Note that \pagecontents +% does insertions, but you have to call it yourself. +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\tt \backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +} + +% Here are the rules for the cropmarks. Note that they are +% offset so that the space between them is truly \outerhsize or \outervsize +% (P. A. MacKay, 12 November, 1986) +% +\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +\def\nstop{\vbox + {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +\def\nsbot{\vbox + {\hrule height\cornerlong depth\cornerthick width\cornerthick}} + +% Parse an argument, then pass it to #1. The argument is the rest of +% the input line (except we remove a trailing comment). #1 should be a +% macro which expects an ordinary undelimited TeX argument. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurence of `\^^M' or `\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarily, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +% +% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my +% favourite TeX trick. --kasal, 16nov03 + +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % Make each space character in the input produce a normal interword + % space in the output. Don't allow a line break at this space, as this + % is used only in environments like @example, where each line of input + % should produce a line of output anyway. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as enviroments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At runtime, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Evironment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + out of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03 + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +%% Simple single-character @ commands + +% @@ prints an @ +% Kludge this until the fonts are right (grr). +\def\@{{\tt\char64}} + +% This is turned off because it was never documented +% and you can use @w{...} around a quote to suppress ligatures. +%% Define @` and @' to be the same as ` and ' +%% but suppressing ligatures. +%\def\`{{`}} +%\def\'{{'}} + +% Used to generate quoted braces. +\def\mylbrace {{\tt\char123}} +\def\myrbrace {{\tt\char125}} +\let\{=\mylbrace +\let\}=\myrbrace +\begingroup + % Definitions to produce \{ and \} commands for indices, + % and @{ and @} for the aux/toc files. + \catcode`\{ = \other \catcode`\} = \other + \catcode`\[ = 1 \catcode`\] = 2 + \catcode`\! = 0 \catcode`\\ = \other + !gdef!lbracecmd[\{]% + !gdef!rbracecmd[\}]% + !gdef!lbraceatcmd[@{]% + !gdef!rbraceatcmd[@}]% +!endgroup + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \c +\let\dotaccent = \. +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \t +\let\ubaraccent = \b +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ptexi + \else\ifx\temp\jmacro \j + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}% + \kern-.15em + \TeX +} + +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on/off}% + \fi\fi +} + +% @w prevents a word break. Without the \leavevmode, @w at the +% beginning of a paragraph, when TeX is still in vertical mode, would +% produce a whole line of output instead of starting the paragraph. +\def\w#1{\leavevmode\hbox{#1}} + +% @group ... @end group forces ... to be all on one page, by enclosing +% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +% to keep its height that of a normal line. According to the rules for +% \topskip (p.114 of the TeXbook), the glue inserted is +% max (\topskip - \ht (first item), 0). If that height is large, +% therefore, no glue is inserted, and the space between the headline and +% the text is small, which looks bad. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an + % end-of-line in the output. We don't want the end-of-line after + % the `@group' to put extra space in the output. Since @group + % should appear on a line by itself (according to the Texinfo + % manual), we don't worry about eating any user text. + \comment +} +% +% The \vtop produces a box with normal height and large depth; thus, TeX puts +% \baselineskip glue before it, and (when the next line of text is done) +% \lineskip glue after it. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \pageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\pageheight + \page + \fi + \fi + \box\groupbox + \prevdepth = \dimen1 + \checkinserts +} +% +% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +% message, so this ends up printing `@group can only ...'. +% +\newhelp\groupinvalidhelp{% +group can only be used in environments such as @example,^^J% +where each line of input produces a line of output.} + +% @need space-in-mils +% forces a page break if there is not space-in-mils remaining. + +\newdimen\mil \mil=0.001in + +% Old definition--didn't work. +%\parseargdef\need{\par % +%% This method tries to make TeX break the page naturally +%% if the depth of the box does not fit. +%{\baselineskip=0pt% +%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak +%\prevdepth=-1000pt +%}} + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\vfil}% + % + % TeX does not even consider page breaks if a penalty added to the + % main vertical list is 10000 or more. But in order to see if the + % empty box we just added fits on the page, we must make it consider + % page breaks. On the other hand, we don't want to actually break the + % page after the empty box. So we use a penalty of 9999. + % + % There is an extremely small chance that TeX will actually break the + % page at this \penalty, if there are no other feasible breakpoints in + % sight. (If the user is using lots of big @group commands, which + % almost-but-not-quite fill up a page, TeX will have a hard time doing + % good page breaking, for example.) However, I could not construct an + % example where a page broke at this \penalty; if it happens in a real + % document, then we can reconsider our strategy. + \penalty9999 + % + % Back up by the size of the box, whether we did a page break or not. + \kern -#1\mil + % + % Do not allow a page break right after this kern. + \nobreak + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @page forces the start of a new page. +% +\def\page{\par\vfill\supereject} + +% @exdent text.... +% outputs text on separate line in roman font, starting at standard page margin + +% This records the amount of indent in the innermost environment. +% That's how much \exdent should take out. +\newskip\exdentamount + +% This defn is used inside fill environments such as @defun. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @include file insert text of that file as input. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable + \def\temp{\input #1 }% + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} + +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\next\centerH + \else + \let\next\centerV + \fi + \next{\hfil \ignorespaces#1\unskip \hfil}% +} +\def\centerH#1{% + {% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break + }% +} +\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} + +% @sp n outputs n lines of vertical space + +\parseargdef\sp{\vskip #1\baselineskip} + +% @comment ...line which is ignored... +% @c is the same as @comment +% @ignore ... @end ignore is another way to write a comment + +\def\comment{\begingroup \catcode`\^^M=\other% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\commentxxx} +{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} + +\let\c=\comment + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent{% + \restorefirstparagraphindent + \indent + }% + \gdef\noindent{% + \restorefirstparagraphindent + \noindent + }% + \global\everypar = {% + \kern -\parindent + \restorefirstparagraphindent + }% +} + +\gdef\restorefirstparagraphindent{% + \global \let \indent = \ptexindent + \global \let \noindent = \ptexnoindent + \global \everypar = {}% +} + + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a \ character. +% FYI, plain.tex uses \\ as a temporary control sequence (why?), but +% this is not advertised and we don't care. Texinfo does not +% otherwise define @\. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + $\finishmath +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + } +} + +% @bullet and @minus need the same treatment as @math, just above. +\def\bullet{$\ptexbullet$} +\def\minus{$-$} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @comma{} is so commas can be inserted into text without messing up +% Texinfo's parsing. +% +\let\comma = , + +% @refill is a no-op. +\let\refill=\relax + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate (before @setfilename). +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% @setfilename is done at the beginning of every texinfo file. +% So open here the files we need to have open while reading the input. +% This makes it possible to make a .fmt file for texinfo. +\def\setfilename{% + \fixbackslash % Turn off hack to swallow `\input texinfo'. + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi % \openindices needs to do some work in any case. + \openindices + \let\setfilename=\comment % Ignore extra @setfilename cmds. + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. + \openin 1 texinfo.cnf + \ifeof 1 \else \input texinfo.cnf \fi + \closein 1 + % + \comment % Ignore the actual filename. +} + +% Called from \setfilename. +% +\def\openindices{% + \newindex{cp}% + \newcodeindex{fn}% + \newcodeindex{vr}% + \newcodeindex{tp}% + \newcodeindex{ky}% + \newcodeindex{pg}% +} + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as \undefined, +% borrowed from ifpdf.sty. +\ifx\pdfoutput\undefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html +% (and related messages, the final outcome is that it is up to the TeX +% user to double the backslashes and otherwise make the string valid, so +% that's what we do). + +% double active backslashes. +% +{\catcode`\@=0 \catcode`\\=\active + @gdef@activebackslashdouble{% + @catcode`@\=@active + @let\=@doublebackslash} +} + +% To handle parens, we must adopt a different approach, since parens are +% not active characters. hyperref.dtx (which has the same problem as +% us) handles it with this amazing macro to replace tokens, with minor +% changes for Texinfo. It is included here under the GPL by permission +% from the author, Heiko Oberdiek. +% +% #1 is the tokens to replace. +% #2 is the replacement. +% #3 is the control sequence with the string. +% +\def\HyPsdSubst#1#2#3{% + \def\HyPsdReplace##1#1##2\END{% + ##1% + \ifx\\##2\\% + \else + #2% + \HyReturnAfterFi{% + \HyPsdReplace##2\END + }% + \fi + }% + \xdef#3{\expandafter\HyPsdReplace#3#1\END}% +} +\long\def\HyReturnAfterFi#1\fi{\fi#1} + +% #1 is a control sequence in which to do the replacements. +\def\backslashparens#1{% + \xdef#1{#1}% redefine it as its expansion; the definition is simply + % \lastnode when called from \setref -> \pdfmkdest. + \HyPsdSubst{(}{\realbackslash(}{#1}% + \HyPsdSubst{)}{\realbackslash)}{#1}% +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros based on pdfcolor.tex. + \def\cmykDarkRed{0.28 1 1 0.35} + \def\cmykBlack{0 0 0 1} + % + \def\pdfsetcolor#1{\pdfliteral{#1 k}} + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\cmykBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .png, .jpg, .pdf (among + % others). Let's try in that order. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \openin 1 #1.pdf \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{pdf}% + \fi + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \closein 1 + \endgroup + % + % without \immediate, pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \imagewidth \fi + \ifdim \wd2 >0pt height \imageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\pdfmkdest#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \turnoffactive + \activebackslashdouble + \makevalueexpandable + \def\pdfdestname{#1}% + \backslashparens\pdfdestname + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + }} + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use a color that is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. + \def\urlcolor{\cmykDarkRed} + \def\linkcolor{\cmykDarkRed} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \def\pdfoutlinedest{#3}% + \ifx\pdfoutlinedest\empty + \def\pdfoutlinedest{#4}% + \else + % Doubled backslashes in the name. + {\activebackslashdouble \xdef\pdfoutlinedest{#3}% + \backslashparens\pdfoutlinedest}% + \fi + % + % Also double the backslashes in the display string. + {\activebackslashdouble \xdef\pdfoutlinetext{#1}% + \backslashparens\pdfoutlinetext}% + % + \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Thanh's hack / proper braces in bookmarks + \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace + \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace + % + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % xx to do this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Right + % now, I guess we'll just let the pdf reader have its way. + \indexnofonts + \setupdatafile + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \ifx\p\space\else\addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \fi + \nextsp} + \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + + +\message{fonts,} + +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname ten#1\endcsname % change the current font +} + +% Select #1 fonts with the current style. +% +\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} +\let\li = \sf % Sometimes we call it \li, not \sf. + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% Default leading. +\newdimen\textleading \textleading = 13.2pt + +% Set the baselineskip to #1, and the lineskip and strut size +% correspondingly. There is no deep meaning behind these magic numbers +% used as factors; they just match (closely enough) what Knuth defined. +% +\def\lineskipfactor{.08333} +\def\strutheightpercent{.70833} +\def\strutdepthpercent {.29167} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% +% PDF CMaps. See also LaTeX's t1.cmap. +% +% \cmapOT1 +\ifpdf + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\else + \expandafter\let\csname cmapOT1\endcsname\gobble + \expandafter\let\csname cmapOT1IT\endcsname\gobble + \expandafter\let\csname cmapOT1TT\endcsname\gobble +\fi + + +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass +% empty to omit). +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble + + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. This is the default in +% Texinfo. +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} +\def\authortt{\sectt} +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acro in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +% reset the current fonts +\textfonts +\rm +} % end of 11pt text font size definitions + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\authorrm{\secrm} +\def\authortt{\sectt} +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acro in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +% reduce space between paragraphs +\divide\parskip by 2 + +% reset the current fonts +\textfonts +\rm +} % end of 10pt text font size definitions + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xword{10} +\def\xiword{11} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + \wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. Since +% texinfo doesn't allow for producing subscripts and superscripts except +% in the main text, we don't bother to reset \scriptfont and +% \scriptscriptfont (which would also require loading a lot more fonts). +% +\def\resetmathfonts{% + \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy + \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf + \textfont\ttfam=\tentt \textfont\sffam=\tensf +} + +% The font-changing commands redefine the meanings of \tenSTYLE, instead +% of just \STYLE. We do this because \STYLE needs to also set the +% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire +% \tenSTYLE to set the current font. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used in +% the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% +\def\textfonts{% + \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl + \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tenttsl=\textttsl + \def\curfontsize{text}% + \def\lsize{reduced}\def\lllsize{smaller}% + \resetmathfonts \setleading{\textleading}} +\def\titlefonts{% + \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl + \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc + \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy + \let\tenttsl=\titlettsl + \def\curfontsize{title}% + \def\lsize{chap}\def\lllsize{subsec}% + \resetmathfonts \setleading{25pt}} +\def\titlefont#1{{\titlefonts\rm #1}} +\def\chapfonts{% + \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl + \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tenttsl=\chapttsl + \def\curfontsize{chap}% + \def\lsize{sec}\def\lllsize{text}% + \resetmathfonts \setleading{19pt}} +\def\secfonts{% + \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl + \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% + \resetmathfonts \setleading{16pt}} +\def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tenttsl=\ssecttsl + \def\curfontsize{ssec}% + \def\lsize{text}\def\lllsize{small}% + \resetmathfonts \setleading{15pt}} +\let\subsubsecfonts = \subsecfonts +\def\reducedfonts{% + \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl + \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc + \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy + \let\tenttsl=\reducedttsl + \def\curfontsize{reduced}% + \def\lsize{small}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallfonts{% + \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl + \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc + \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy + \let\tenttsl=\smallttsl + \def\curfontsize{small}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{10.5pt}} +\def\smallerfonts{% + \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl + \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc + \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy + \let\tenttsl=\smallerttsl + \def\curfontsize{smaller}% + \def\lsize{smaller}\def\lllsize{smaller}% + \resetmathfonts \setleading{9.5pt}} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% +% I wish the USA used A4 paper. +% --karl, 24jan03. + + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + +% Define these so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + +%% Add scribe-like font environments, plus @l for inline lisp (usually sans +%% serif) and @ii for TeX italic + +% \smartitalic{ARG} outputs arg in italics, followed by an italic correction +% unless the following character is such as not to need one. +\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else + \ptexslash\fi\fi\fi} +\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx} +\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx} + +% like \smartslanted except unconditionally uses \ttsl. +% @var is set to this for defun arguments. +\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx} + +% like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitalicx} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\var=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% @b, explicit bold. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% We can't just use \exhyphenpenalty, because that only has effect at +% the end of a paragraph. Restore normal hyphenation at the end of the +% group within which \nohyphenation is presumably called. +% +\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +\def\restorehyphenation{\hyphenchar\font = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m + \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} +\def\samp#1{`\tclose{#1}'\null} +\setfont\keyrm\rmshape{8}{1000}{OT1} +\font\keysy=cmsy9 +\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% + \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% + \vbox{\hrule\kern-0.4pt + \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% + \kern-0.4pt\hrule}% + \kern-.06em\raise0.4pt\hbox{\angleright}}}} +\def\key #1{{\nohyphenation \uppercase{#1}}\null} +% The old definition, with no lozenge: +%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + +% @file, @option are the same as @samp. +\let\file=\samp +\let\option=\samp + +% @code is a modification of @t, +% which makes spaces the same size as normal in the surrounding text. +\def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. + \spaceskip = \fontdimen2\font + % + % Switch to typewriter. + \tt + % + % But `\ ' produces the large typewriter interword space. + \def\ {{\spaceskip = 0pt{} }}% + % + % Turn off hyphenation. + \nohyphenation + % + \rawbackslash + \plainfrenchspacing + #1% + }% + \null +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% Otherwise, it is too hard to avoid overfull hboxes +% in the Emacs manual, the Library manual, etc. + +% Unfortunately, TeX uses one parameter (\hyphenchar) to control +% both hyphenation at - and hyphenation within words. +% We must therefore turn them both off (\tclose does that) +% and arrange explicitly to hyphenate at a dash. +% -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + % + \global\def\code{\begingroup + \catcode\rquoteChar=\active \catcode\lquoteChar=\active + \let'\codequoteright \let`\codequoteleft + % + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\realdash + \let_\realunder + \fi + \codex + } +} + +\def\realdash{-} +\def\codedash{-\discretionary{}{}{}} +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} +\def\codex #1{\tclose{#1}\endgroup} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is undesirable in +% some manuals, especially if they don't have long identifiers in +% general. @allowcodebreaks provides a way to control this. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg'}% + \fi\fi +} + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle option `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct.' +\kbdinputstyle distinct + +\def\xkey{\key} +\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +\ifx\one\xkey\ifx\threex\three \key{#2}% +\else{\tclose{\kbdfont\look}}\fi +\else{\tclose{\kbdfont\look}}\fi} + +% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. +\let\indicateurl=\code +\let\env=\code +\let\command=\code + +% @uref (abbreviation for `urlref') takes an optional (comma-separated) +% second argument specifying the text to display and an optional third +% arg as text to display instead of (rather than in addition to) the url +% itself. First (mandatory) arg is the url. Perhaps eventually put in +% a hypertex \special here. +% +\def\uref#1{\douref #1,,,\finish} +\def\douref#1,#2,#3,#4\finish{\begingroup + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \ifpdf + \unhbox0 % PDF: 2nd arg given, show only it + \else + \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url + \fi + \else + \code{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \let\email=\uref +\fi + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +% +\def\dmn#1{\thinspace #1} + +\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} + +% @l was never documented to mean ``switch to the Lisp font'', +% and it is not used as such in any manual I can find. We need it for +% Polish suppressed-l. --karl, 22sep96. +%\def\l#1{{\li #1}\null} + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\selectfonts\lsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi +} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Hacks for glyphs from the EC fonts similar to \euro. We don't +% use \let for the aliases, because sometimes we redefine the original +% macro, and the alias should reflect the redefinition. +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +\def\ecfont{% + % We can't distinguish serif/sanserif and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\undefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% Do an implicit @contents or @shortcontents after @end titlepage if the +% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +% +\newif\ifsetcontentsaftertitlepage + \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +\newif\ifsetshortcontentsaftertitlepage + \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue + +\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % Most title ``pages'' are actually two pages long, with space + % at the top of the second. We don't want the ragged left on the second. + \let\oldpage = \page + \def\page{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + \let\page = \oldpage + \page + \null + }% +} + +\def\Etitlepage{% + \iffinishedtitlepage\else + \finishtitlepage + \fi + % It is important to do the page break before ending the group, + % because the headline and footline are only empty inside the group. + % If we use the new definition of \page, we always get a blank page + % after the title page, which we certainly don't want. + \oldpage + \endgroup + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon + % + % If they want short, they certainly want long too. + \ifsetshortcontentsaftertitlepage + \shortcontents + \contents + \global\let\shortcontents = \relax + \global\let\contents = \relax + \fi + % + \ifsetcontentsaftertitlepage + \contents + \global\let\contents = \relax + \global\let\shortcontents = \relax + \fi +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +%%% Macros to be used within @titlepage: + +\let\subtitlerm=\tenrm +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines + \let\tt=\authortt} + +\parseargdef\title{% + \checkenv\titlepage + \leftline{\titlefonts\rm #1} + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\authorfont \leftline{#1}}% + \fi +} + + +%%% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make TeX use those variables +\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline + \else \the\evenheadline \fi}} +\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline + \else \the\evenfootline \fi}\HEADINGShook} +\let\HEADINGShook=\relax + +% Commands to set those variables. +% For example, this is what @headings on does +% @evenheading @thistitle|@thispage|@thischapter +% @oddheading @thischapter|@thispage|@thistitle +% @evenfooting @thisfile|| +% @oddfooting ||@thisfile + + +\def\evenheading{\parsearg\evenheadingxxx} +\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\pageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @headings double turns headings on for double-sided printing. +% @headings single turns headings on for single-sided printing. +% @headings off turns them off. +% @headings on same as @headings double, retained for compatibility. +% @headings after turns on double-sided headings after this page. +% @headings doubleafter turns on double-sided headings after this page. +% @headings singleafter turns on single-sided headings after this page. +% By default, they are off at the start of a document, +% and turned `on' after @end titlepage. + +\def\headings #1 {\csname HEADINGS#1\endcsname} + +\def\HEADINGSoff{% +\global\evenheadline={\hfil} \global\evenfootline={\hfil} +\global\oddheadline={\hfil} \global\oddfootline={\hfil}} +\HEADINGSoff +% When we turn headings on, set the page number to 1. +% For double-sided printing, put current file name in lower left corner, +% chapter name on inside top of right hand pages, document +% title on inside top of left hand pages, and page numbers on outside top +% edge of all pages. +\def\HEADINGSdouble{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\def\HEADINGSon{\HEADINGSdouble} + +\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +\let\HEADINGSdoubleafter=\HEADINGSafter +\def\HEADINGSdoublex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapter\hfil\folio}} +\global\oddheadline={\line{\thischapter\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\undefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(x). + +% default indentation of table text +\newdimen\tableindent \tableindent=.8in +% default indentation of @itemize and @enumerate text +\newdimen\itemindent \itemindent=.3in +% margin between end of table item and start of table text. +\newdimen\itemmargin \itemmargin=.1in + +% used internally for \itemindent minus \itemmargin +\newdimen\itemmax + +% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +% these defs. +% They also define \itemindex +% to index the item name in whatever manner is desired (perhaps none). + +\newif\ifitemxneedsnegativevskip + +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % If the item text does not fit in the space we have, put it on a line + % by itself, and do not allow a page break either before or after that + % line. We do not start a paragraph here because then if the next + % command is, e.g., @kindex, the whatsit would get put into the + % horizontal list on a line by itself, resulting in extra blank space. + \ifdim \wd0>\itemmax + % + % Make this a paragraph so we get the \parskip glue and wrapping, + % but leave it ragged-right. + \begingroup + \advance\leftskip by-\tableindent + \advance\hsize by\tableindent + \advance\rightskip by0pt plus1fil + \leavevmode\unhbox0\par + \endgroup + % + % We're going to be starting a paragraph, but we don't want the + % \parskip glue -- logically it's part of the @item we just started. + \nobreak \vskip-\parskip + % + % Stop a page break at the \parskip glue coming up. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \endgroup + \itemxneedsnegativevskipfalse + \else + % The item text fits into the space. Start a paragraph, so that the + % following text (if any) will end up on the same line. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + \def\itemcontents{#1}% + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + \vadjust{\penalty 1200}}% not good to break after first line of item. + \flushcr +} + +% \splitoff TOKENS\endmark defines \first to be the first token in +% TOKENS, and \rest to be the remainder. +% +\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% + +% Allow an optional argument of an uppercase letter, lowercase letter, +% or number, to specify the first label in the enumerated list. No +% argument is the same as `1'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % If we were given no argument, pretend we were given `1'. + \def\thearg{#1}% + \ifx\thearg\empty \def\thearg{1}\fi + % + % Detect if the argument is a single token. If so, it might be a + % letter. Otherwise, the only valid thing it can be is a number. + % (We will always have one token, because of the test we just made. + % This is a good thing, since \splitoff doesn't work given nothing at + % all -- the first parameter is undelimited.) + \expandafter\splitoff\thearg\endmark + \ifx\rest\empty + % Only one token in the argument. It could still be anything. + % A ``lowercase letter'' is one whose \lccode is nonzero. + % An ``uppercase letter'' is one whose \lccode is both nonzero, and + % not equal to itself. + % Otherwise, we assume it's a number. + % + % We need the \relax at the end of the \ifnum lines to stop TeX from + % continuing to look for a . + % + \ifnum\lccode\expandafter`\thearg=0\relax + \numericenumerate % a number (we hope) + \else + % It's a letter. + \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax + \lowercaseenumerate % lowercase letter + \else + \uppercaseenumerate % uppercase letter + \fi + \fi + \else + % Multiple tokens in the argument. We hope it's a number. + \numericenumerate + \fi +} + +% An @enumerate whose labels are integers. The starting integer is +% given in \thearg. +% +\def\numericenumerate{% + \itemno = \thearg + \startenumeration{\the\itemno}% +} + +% The starting (lowercase) letter is in \thearg. +\def\lowercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more lowercase letters in @enumerate; get a bigger + alphabet}% + \fi + \char\lccode\itemno + }% +} + +% The starting (uppercase) letter is in \thearg. +\def\uppercaseenumerate{% + \itemno = \expandafter`\thearg + \startenumeration{% + % Be sure we're not beyond the end of the alphabet. + \ifnum\itemno=0 + \errmessage{No more uppercase letters in @enumerate; get a bigger + alphabet} + \fi + \char\uccode\itemno + }% +} + +% Call \doitemize, adding a period to the first argument and supplying the +% common last two arguments. Also subtract one from the initial value in +% \itemno, since @item increments \itemno. +% +\def\startenumeration#1{% + \advance\itemno by -1 + \doitemize{#1.}\flushcr +} + +% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +% to @enumerate. +% +\def\alphaenumerate{\enumerate{a}} +\def\capsenumerate{\enumerate{A}} +\def\Ealphaenumerate{\Eenumerate} +\def\Ecapsenumerate{\Eenumerate} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab do not need to be on their own lines, but it will not hurt +% if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. +% Assignments have to be global since we are inside the implicit group +% of an alignment entry. Note that \everycr resets \everytab. +\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}% +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we encounter the problem it was intended to solve again. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% + \global\colcount=0 % Reset the column counter. + % Check for saved footnotes, etc. + \checkinserts + % Keeps underfull box messages off when table breaks over pages. + %\filbreak + % Maybe so, but it also creates really weird page breaks when the + % table breaks over pages. Wouldn't \vfil be better? Wait until the + % problem manifests itself, so it can be fixed for real --karl. + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. + \halign\bgroup &% + \global\advance\colcount by 1 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the user has set preamble in terms of percent of \hsize we will + % use that dimension as the width of the column, and the \leftskip + % will keep entries from bumping into each other. Table will start at + % left margin and final column will justify at right margin. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @set VAR sets the variable VAR to an empty value. +% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +% +% Since we want to separate VAR from REST-OF-LINE (which might be +% empty), we can't just use \parsearg; we have to insert a space of our +% own to delimit the rest of the line, and then take it out again if we +% didn't need it. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\- = \active \catcode`\_ = \active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\realdash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get special treatment of `@end ifset,' call \makeond and the redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named foo. +% It automatically defines \fooindex such that +% \fooindex ...rest of line... puts an entry in the index foo. +% It also defines \fooindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is foo. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 % Open the file + \fi + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \iflinks + \expandafter\newwrite \csname#1indfile\endcsname + \openout \csname#1indfile\endcsname \jobname.#1 + \fi + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + + +% @synindex foo bar makes index foo feed into index bar. +% Do this instead of @defindex foo if you don't want it as a separate index. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + % Only do \closeout if we haven't already done it, else we'll end up + % closing the target index. + \expandafter \ifx\csname donesynindex#2\endcsname \undefined + % The \closeout helps reduce unnecessary open files; the limit on the + % Acorn RISC OS is a mere 16 files. + \expandafter\closeout\csname#2indfile\endcsname + \expandafter\let\csname\donesynindex#2\endcsname = 1 + \fi + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all \fooindex macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is "foo", the name of the index. + +% \doindex just uses \parsearg; it calls \doind for the actual work. +% This is because \doind is more useful to call from other macros. + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +\def\singleindexer #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} + +% Take care of Texinfo commands that can appear in an index entry. +% Since there are some commands we want to expand, and others we don't, +% we have to laboriously prevent expansion for those that we don't. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \def\@{@}% change to @@ when we switch to @ as escape char in index files. + \def\ {\realbackslash\space }% + % + % Need these in case \tex is in effect and \{ is a \delimiter again. + % But can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. + \let\{ = \mylbrace + \let\} = \myrbrace + % + % I don't entirely understand this, but when an index entry is + % generated from a macro call, the \endinput which \scanmacro inserts + % causes processing to be prematurely terminated. This is, + % apparently, because \indexsorttmp is fully expanded, and \endinput + % is an expandable command. The redefinition below makes \endinput + % disappear altogether for that purpose -- although logging shows that + % processing continues to some further point. On the other hand, it + % seems \endinput does not hurt in the printed index arg, since that + % is still getting written without apparent harm. + % + % Sample source (mac-idx3.tex, reported by Graham Percival to + % help-texinfo, 22may06): + % @macro funindex {WORD} + % @findex xyz + % @end macro + % ... + % @funindex commtest + % + % The above is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} + % + % So: + \let\endinput = \empty + % + % Do the redefinitions. + \commondummies +} + +% For the aux and toc files, @ is the escape character. So we want to +% redefine everything using @ as the escape character (instead of +% \realbackslash, still used for index files). When everything uses @, +% this will be simpler. +% +\def\atdummies{% + \def\@{@@}% + \def\ {@ }% + \let\{ = \lbraceatcmd + \let\} = \rbraceatcmd + % + % Do the redefinitions. + \commondummies + \otherbackslash +} + +% Called from \indexdummies and \atdummies. +% +\def\commondummies{% + % + % \definedummyword defines \#1 as \string\#1\space, thus effectively + % preventing its expansion. This is used only for control% words, + % not control letters, because the \space would be incorrect for + % control characters, but is needed to separate the control word + % from whatever follows. + % + % For control letters, we have \definedummyletter, which omits the + % space. + % + % These can be used both for control words that take an argument and + % those that do not. If it is followed by {arg} in the input, then + % that will dutifully get written to the index (or wherever). + % + \def\definedummyword ##1{\def##1{\string##1\space}}% + \def\definedummyletter##1{\def##1{\string##1}}% + \let\definedummyaccent\definedummyletter + % + \commondummiesnofonts + % + \definedummyletter\_% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\L + \definedummyword\OE + \definedummyword\O + \definedummyword\aa + \definedummyword\ae + \definedummyword\l + \definedummyword\oe + \definedummyword\o + \definedummyword\ss + \definedummyword\exclamdown + \definedummyword\questiondown + \definedummyword\ordf + \definedummyword\ordm + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\expansion + \definedummyword\minus + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\result + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + % + \normalturnoffactive + % + % Handle some cases of @value -- where it does not contain any + % (non-fully-expandable) commands. + \makevalueexpandable +} + +% \commondummiesnofonts: common to \commondummies and \indexnofonts. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \definedummyletter\!% + \definedummyaccent\"% + \definedummyaccent\'% + \definedummyletter\*% + \definedummyaccent\,% + \definedummyletter\.% + \definedummyletter\/% + \definedummyletter\:% + \definedummyaccent\=% + \definedummyletter\?% + \definedummyaccent\^% + \definedummyaccent\`% + \definedummyaccent\~% + \definedummyword\u + \definedummyword\v + \definedummyword\H + \definedummyword\dotaccent + \definedummyword\ringaccent + \definedummyword\tieaccent + \definedummyword\ubaraccent + \definedummyword\udotaccent + \definedummyword\dotless + % + % Texinfo font commands. + \definedummyword\b + \definedummyword\i + \definedummyword\r + \definedummyword\sc + \definedummyword\t + % + % Commands that take arguments. + \definedummyword\acronym + \definedummyword\cite + \definedummyword\code + \definedummyword\command + \definedummyword\dfn + \definedummyword\emph + \definedummyword\env + \definedummyword\file + \definedummyword\kbd + \definedummyword\key + \definedummyword\math + \definedummyword\option + \definedummyword\pxref + \definedummyword\ref + \definedummyword\samp + \definedummyword\strong + \definedummyword\tie + \definedummyword\uref + \definedummyword\url + \definedummyword\var + \definedummyword\verb + \definedummyword\w + \definedummyword\xref +} + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\definedummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\definedummyletter##1{\let##1\empty}% + % Hopefully, all control words can become @asis. + \let\definedummyword\definedummyaccent + % + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + % how to handle braces? + \def\_{\normalunderscore}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\aa{aa}% + \def\ae{ae}% + \def\l{l}% + \def\oe{oe}% + \def\o{o}% + \def\ss{ss}% + \def\exclamdown{!}% + \def\questiondown{?}% + \def\ordf{a}% + \def\ordm{o}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. + % (The following {} will end up in the sort string, but that's ok.) + \def\bullet{bullet}% + \def\comma{,}% + \def\copyright{copyright}% + \def\registeredsymbol{R}% + \def\dots{...}% + \def\enddots{...}% + \def\equiv{==}% + \def\error{error}% + \def\euro{euro}% + \def\guillemetleft{<<}% + \def\guillemetright{>>}% + \def\guilsinglleft{<}% + \def\guilsinglright{>}% + \def\expansion{==>}% + \def\minus{-}% + \def\pounds{pounds}% + \def\point{.}% + \def\print{-|}% + \def\quotedblbase{"}% + \def\quotedblleft{"}% + \def\quotedblright{"}% + \def\quoteleft{`}% + \def\quoteright{'}% + \def\quotesinglbase{,}% + \def\result{=>}% + \def\textdegree{degrees}% + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist +} + +\let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% Workhorse for all \fooindexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Write the entry in \toks0 to the index file: +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now + % so it will be output as is; and it will print as backslash. + % + % Process the index entry with all font commands turned off, to + % get the string to sort by. + {\indexnofonts + \edef\temp{\the\toks0}% need full expansion + \xdef\indexsorttmp{\temp}% + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{% +\ifhmode + #1% +\else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi +} + +% The index entry written in the file actually looks like +% \entry {sortstring}{page}{topic} +% or +% \entry {sortstring}{page}{topic}{subtopic} +% The texindex program reads in these files and writes files +% containing these kinds of lines: +% \initial {c} +% before the first topic whose initial is c +% \entry {topic}{pagelist} +% for a topic that is used without subtopics +% \primary {topic} +% for the beginning of a topic that is used with subtopics +% \secondary {subtopic}{pagelist} +% for each subtopic. + +% Define the user-accessible indexing commands +% @findex, @vindex, @kindex, @cindex. + +\def\findex {\fnindex} +\def\kindex {\kyindex} +\def\cindex {\cpindex} +\def\vindex {\vrindex} +\def\tindex {\tpindex} +\def\pindex {\pgindex} + +\def\cindexsub {\begingroup\obeylines\cindexsub} +{\obeylines % +\gdef\cindexsub "#1" #2^^M{\endgroup % +\dosubind{cp}{#2}{#1}}} + +% Define the macros used in formatting output of the sorted index material. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 11 + \openin 1 \jobname.#1s + \ifeof 1 + % \enddoublecolumns gets confused if there is no text in the index, + % and it loses the chapter title and the aux file entries for the + % index. The easiest way to prevent this problem is to make sure + % there is some text. + \putwordIndexNonexistent + \else + % + % If the index file exists but is empty, then \openin leaves \ifeof + % false. We have to make TeX try to read something from the file, so + % it can discover if there is anything in it. + \read 1 to \temp + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\backslashcurfont}% + \catcode`\\ = 0 + \escapechar = `\\ + \begindoublecolumns + \input \jobname.#1s + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +\def\initial#1{{% + % Some minor font changes for the special characters. + \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt + % + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + \nobreak + \vskip 0pt plus 3\baselineskip + \penalty 0 + \vskip 0pt plus -3\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus .5\baselineskip + \leftline{\secbf #1}% + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip +}} + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +% A straightforward implementation would start like this: +% \def\entry#1#2{... +% But this frozes the catcodes in the argument, and can cause problems to +% @code, which sets - active. This problem was fixed by a kludge--- +% ``-'' was active throughout whole index, but this isn't really right. +% +% The right solution is to prevent \entry from swallowing the whole text. +% --kasal, 21nov03 +\def\entry{% + \begingroup + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % Do not fill out the last line with white space. + \parfillskip = 0in + % + % No extra space above this paragraph. + \parskip = 0in + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % \hangindent is only relevant when the entry text and page number + % don't both fit on one line. In that case, bob suggests starting the + % dots pretty far over on the line. Unfortunately, a large + % indentation looks wrong when the entry text itself is broken across + % lines. So we use a small indentation and put up with long leaders. + % + % \hangafter is reset to 1 (which is the value we want) at the start + % of each paragraph, so we need not do anything with that. + \hangindent = 2em + % + % When the entry text needs to be broken, just fill out the first line + % with blank space. + \rightskip = 0pt plus1fil + % + % A bit of stretch before each entry for the benefit of balancing + % columns. + \vskip 0pt plus1pt + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\doentry{% + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. +} +\def\finishentry#1{% + % #1 is the page number. + % + % The following is kludged to not output a line of dots in the index if + % there are no page numbers. The next person who breaks this will be + % cursed by a Unix daemon. + \setbox\boxA = \hbox{#1}% + \ifdim\wd\boxA = 0pt + \ % + \else + % + % If we must, put the page number on a line of its own, and fill out + % this line with blank space. (The \hfil is overwhelmed with the + % fill leaders glue in \indexdotfill if the page number does fit.) + \hfil\penalty50 + \null\nobreak\indexdotfill % Have leaders before the page number. + % + % The `\ ' here is removed by the implicit \unskip that TeX does as + % part of (the primitive) \par. Without it, a spurious underfull + % \hbox ensues. + \ifpdf + \pdfgettoks#1.% + \ \the\toksA + \else + \ #1% + \fi + \fi + \par + \endgroup +} + +% Like plain.tex's \dotfill, except uses up at least 1 em. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} + +\def\primary #1{\line{#1\hfil}} + +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + #2 + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 + +\newbox\partialpage +\newdimen\doublecolumnhsize + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + }% + \eject % run that output routine to set \partialpage + % + % Use the double-column output routine for subsequent pages. + \output = {\doublecolumnout}% + % + % Change the page size parameters. We could do this once outside this + % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 + % format, but then we repeat the same computation. Repeating a couple + % of assignments once per index is clearly meaningless for the + % execution time, so we may as well do it in one place. + % + % First we halve the line length, less a little for the gutter between + % the columns. We compute the gutter based on the line length, so it + % changes automatically with the paper format. The magic constant + % below is chosen so that the gutter has the same value (well, +-<1pt) + % as it did when we hard-coded it. + % + % We put the result in a separate register, \doublecolumhsize, so we + % can restore it in \pagesofar, after \hsize itself has (potentially) + % been clobbered. + % + \doublecolumnhsize = \hsize + \advance\doublecolumnhsize by -.04154\hsize + \divide\doublecolumnhsize by 2 + \hsize = \doublecolumnhsize + % + % Double the \vsize as well. (We don't need a separate register here, + % since nobody clobbers \vsize.) + \vsize = 2\vsize +} + +% The double-column output routine for all double-column pages except +% the last. +% +\def\doublecolumnout{% + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + \advance\dimen@ by -\ht\partialpage + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \onepageout\pagesofar + \unvbox255 + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\pagewidth{\box0\hfil\box2}% +} +% +% All done with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \pageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. Leave it on the + % current page, no automatic page break. + \balancecolumns + % + % If we end up splitting too much material for the current page, + % though, there will be another page break right after this \output + % invocation ends. Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. (We hope \balancecolumns will never be + % called on to balance too much material, but if it is, this makes + % the output somewhat more palatable.) + \global\output = {\onepageout{\pagecontents\PAGE}}% + }% + \eject + \endgroup % started in \begindoublecolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize (after the + % \endgroup where \vsize got restored). + \pagegoal = \vsize +} +% +% Called at the end of the double column material. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \divide\dimen@ by 2 % target to split to + %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% + \splittopskip = \topskip + % Loop until we get a decent breakpoint. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht3>\dimen@ + \global\advance\dimen@ by 1pt + \repeat + }% + %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% + \setbox0=\vbox to\dimen@{\unvbox1}% + \setbox2=\vbox to\dimen@{\unvbox3}% + % + \pagesofar +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% \unnumberedno is an oxymoron, of course. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\newcount\chapno +\newcount\secno \secno=0 +\newcount\subsecno \subsecno=0 +\newcount\subsubsecno \subsubsecno=0 + +% This counter is funny since it counts through charcodes of letters A, B, ... +\newcount\appendixno \appendixno = `\@ +% +% \def\appendixletter{\char\the\appendixno} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count + +% @raisesections: treat @section as chapter, @subsection as section, etc. +\def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name + +% @lowersections: treat @chapter as section, @section as subsection, etc. +\def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achive this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unmlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unmlevel + \chardef\unmlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unmlevel + \def\headtype{U}% + \else + \chardef\unmlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + \message{\putwordChapter\space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + \def\appendixnum{\putwordAppendix\space \appendixletter}% + \message{\appendixnum}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % This used to be simply \message{#1}, but TeX fully expands the + % argument to \message. Therefore, if #1 contained @-commands, TeX + % expanded them. For example, in `@unnumbered The @cite{Book}', TeX + % expanded @cite (which turns out to cause errors because \cite is meant + % to be executed, not expanded). + % + % Anyway, we don't want the fully-expanded definition of @cite to appear + % as a result of the \message, we just want `@cite' itself. We use + % \the to achieve this: TeX expands \the only once, + % simply yielding the contents of . (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + % Well, we could do the following in a group, but that would break + % an assumption that \chapmacro is called at the outermost level. + % Thus we are safer this way: --kasal, 24feb04 + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% These macros control what the section commands do, according +% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +% Define them by default for a numbered chapter. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +% NOTE on use of \vbox for chapter headings, section headings, and such: +% 1) We use \vbox rather than the earlier \line to permit +% overlong headings to fold. +% 2) \hyphenpenalty is set to 10000 because hyphenation in a +% heading is obnoxious; this forbids it. +% 3) Likewise, headings look best if no \parindent is used, and +% if justification is not attempted. Hence \raggedright. + + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}% + \bigskip \par\penalty 200\relax + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% These macros generate a chapter, section, etc. heading only +% (including whitespace, linebreaking, etc. around it), +% given all the information in convenient, parsed form. + +%%% Args are the skip and penalty (usually negative) +\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} + +%%% Define plain chapter starts, and page on/off switching for it +% Parameter controlling skip before chapter headings (if needed) + +\newskip\chapheadingskip + +\def\chapbreak{\dobreak \chapheadingskip {-4000}} +\def\chappager{\par\vfill\supereject} +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% + \hbox to 0pt{}% + \chappager + \endgroup + \fi +} + +\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yomitfromtockeyword{Yomitfromtoc} +\def\Yappendixkeyword{Yappendix} +% +\def\chapmacro#1#2#3{% + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + \gdef\noexpand\thischapter{\putwordAppendix{} \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + \gdef\noexpand\thischapter{\putwordChapter{} \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rm + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% I don't think this chapter style is supported any more, so I'm not +% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +% +\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} +% +\def\unnchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt\raggedright + \rm #1\hfill}}\bigskip \par\nobreak +} +\def\chfopen #1#2{\chapoddpage {\chapfonts +\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +\par\penalty 5000 % +} +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\nobreak +} +\def\CHAPFopen{% + \global\let\chapmacro=\chfopen + \global\let\centerchapmacro=\centerchfopen} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is +% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the +% section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + \gdef\noexpand\thissection{\putwordSection{} \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) + \vskip-\parskip + % + % This is purely so the last item on the list is a known \penalty > + % 10000. This is so \startdefun can avoid allowing breakpoints after + % section headings. Otherwise, it would insert a valid breakpoint between: + % + % @section sec-whatever + % @deffn def-whatever + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf \global\pdfmakepagedesttrue \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \advance\hsize by -\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% These macros generate individual entries in the table of contents. +% The first argument is the chapter or section name. +% The last argument is the page number. +% The arguments in between are the chapter number, section number, ... + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +% +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% Now for the actual typesetting. In all these, #1 is the text and #2 is the +% page number. +% +% If the toc has to be broken over pages, we want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% Space between chapter (or whatever) number and the title. +\def\labelspace{\hskip1em \relax} + +\def\dopageno#1{{\rm #1}} +\def\doshortpageno#1{{\rm #1}} + +\def\chapentryfonts{\secfonts \rm} +\def\secentryfonts{\textfonts} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, it should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\tentt \global\dimen0 = 3em}% Width of the box. +\dimen2 = .55pt % Thickness of rules +% The text. (`r' is open on the right, `e' somewhat less so on the left.) +\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt} +% +\setbox\errorbox=\hbox to \dimen0{\hfil + \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. + \advance\hsize by -2\dimen2 % Rules. + \vbox{% + \hrule height\dimen2 + \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. + \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. + \kern3pt\vrule width\dimen2}% Space to right. + \hrule height\dimen2} + \hfil} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @tex ... @end tex escapes into raw Tex temporarily. +% One exception: @ is still an escape character, so that @end tex works. +% But \@ or @@ will get a plain tex @ character. + +\envdef\tex{% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \escapechar=`\\ + % + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (which normally is erroneous). + +% Amount to narrow the margins by for @lisp. +\newskip\lispnarrowing \lispnarrowing=0.4in + +% This is the definition that ^^M gets inside @lisp, @example, and other +% such environments. \null is better than a space, since it doesn't +% have any width. +\def\lisppar{\null\endgraf} + +% This space is always present above and below environments. +\newskip\envskipamount \envskipamount = 0pt + +% Make spacing and below environment symmetrical. We use \parskip here +% to help in doing that, since in @example-like environments \parskip +% is reset to zero; thus the \afterenvbreak inserts no space -- but the +% start of the next paragraph will insert \parskip. +% +\def\aboveenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +\let\afterenvbreak = \aboveenvbreak + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle +% +\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +\def\ctr{{\hskip 6pt\circle\char'010}} +\def\cbl{{\circle\char'012\hskip -6pt}} +\def\cbr{{\hskip 6pt\circle\char'011}} +\def\carttop{\hbox to \cartouter{\hskip\lskip + \ctl\leaders\hrule height\circthick\hfil\ctr + \hskip\rskip}} +\def\cartbot{\hbox to \cartouter{\hskip\lskip + \cbl\leaders\hrule height\circthick\hfil\cbr + \hskip\rskip}} +% +\newskip\lskip\newskip\rskip + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \lskip=\leftskip \rskip=\rightskip + \leftskip=0pt\rightskip=0pt % we want these *outside*. + \cartinner=\hsize \advance\cartinner by-\lskip + \advance\cartinner by-\rskip + \cartouter=\hsize + \advance\cartouter by 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % Flag to tell @lisp, etc., not to narrow margin. + \let\nonarrowing = t% + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of \def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\def\nonfillstart{% + \aboveenvbreak + \hfuzz = 12pt % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + \parindent = 0pt + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it by one command: +\def\makedispenv #1#2{ + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2} + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2} + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two synonyms: +\def\maketwodispenvs #1#2#3{ + \makedispenv{#1}{#3} + \makedispenv{#2}{#3} +} + +% @lisp: indented, narrowed, typewriter font; @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvs {lisp}{example}{% + \nonfillstart + \tt\quoteexpand + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenv {display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenv{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\envdef\quotation{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\undefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + + +% LaTeX-like @verbatim...@end verbatim and @verb{...} +% If we want to allow any as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% [Knuth] pp. 380,381,391 +% Disable Spanish ligatures ?` and !` of \tt font +\begingroup + \catcode`\`=\active\gdef`{\relax\lq} +\endgroup +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \catcode`\`=\active + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +\def\starttabbox{\setbox0=\hbox\bgroup} + +% Allow an option to not replace quotes with a regular directed right +% quote/apostrophe (char 0x27), but instead use the undirected quote +% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it +% the default, but it works for pasting with more pdf viewers (at least +% evince), the lilypond developers report. xpdf does work with the +% regular 0x27. +% +\def\codequoteright{% + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + `% + \else \char'22 \fi + \else \char'22 \fi +} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen0=\wd0 % the width so far, or since the previous tab + \divide\dimen0 by\tabw + \multiply\dimen0 by\tabw % compute previous multiple of \tabw + \advance\dimen0 by\tabw % advance to next multiple of \tabw + \wd0=\dimen0 \box0 \starttabbox + }% + } + \catcode`\'=\active + \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}% + % + \catcode`\`=\active + \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}% + % + \gdef\quoteexpand{\rquoteexpand \lquoteexpand}% +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + % Easiest (and conventionally used) font for verbatim + \tt + \def\par{\leavevmode\egroup\box0\endgraf}% + \catcode`\`=\active + \tabexpand + \quoteexpand + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'#1'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is very desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a minor refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remainnig is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +%%% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +%%% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +%%% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +%%% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +%%% Type: +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % How we'll format the type name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % (plain.tex says that \dimen1 should be used only as global.) + \parshape 2 0in \dimen0 \defargsindent \dimen2 + % + % Put the type name to the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% return value type + \ifx\temp\empty\else \tclose{\temp} \fi + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \tenrm + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. Let's try @var for that. + \let\var=\ttslanted + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\def\activeparens{% + \catcode`\(=\active \catcode`\)=\active + \catcode`\[=\active \catcode`\]=\active + \catcode`\&=\active +} + +% Make control sequences which act like normal parenthesis chars. +\let\lparen = ( \let\rparen = ) + +% Be sure that we always have a definition for `(', etc. For example, +% if the fn name has parens in it, \boldbrax will not be in effect yet, +% so TeX would otherwise complain about undefined control sequence. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\undefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +\def\scanmacro#1{% + \begingroup + \newlinechar`\^^M + \let\xeatspaces\eatspaces + % Undo catcode changes of \startcontents and \doprintindex + % When called from @insertcopying or (short)caption, we need active + % backslash to get it printed correctly. Previously, we had + % \catcode`\\=\other instead. We'll see whether a problem appears + % with macro expansion. --kasal, 19aug04 + \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ + % ... and \example + \spaceisspace + % + % Append \endinput to make sure that TeX does not see the ending newline. + % I've verified that it is necessary both for e-TeX and for ordinary TeX + % --kasal, 29nov03 + \scantokens{#1\endinput}% + \endgroup +} + +\def\scanexp#1{% + \edef\temp{\noexpand\scanmacro{#1}}% + \temp +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \definedummyword\macro1\definedummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\definedummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \. + +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. + +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. + +\def\scanctxt{% + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\@=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi +} + +\def\scanargctxt{% + \scanctxt + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% + \scanctxt + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +\def\macroargctxt{% + \scanctxt + \catcode`\\=\other +} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. + +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0% + \else + \expandafter\parsemargdef \argl;% + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\definedummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\definedummyword \noexpand#1% + \fi +} + +% This makes use of the obscure feature that if the last token of a +% is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname #1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} + +% Parse the optional {params} list. Set up \paramno and \paramlist +% so \defmacro knows what to do. Define \macarg.blah for each blah +% in the params list, to be ##N where N is the position in that list. +% That gets used by \mbodybackslash (above). + +% We need to get `macro parameter char #' into several definitions. +% The technique used is stolen from LaTeX: let \hash be something +% unexpandable, insert that wherever you need a #, and then redefine +% it to # just before using the token list produced. +% +% The same technique is used to protect \eatspaces till just before +% the macro is used. + +\def\parsemargdef#1;{\paramno=0\def\paramlist{}% + \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1% + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% These two commands read recursive and nonrecursive macro bodies. +% (They're different since rec and nonrec macros end differently.) + +\long\def\parsemacbody#1@end macro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +\long\def\parsermacbody#1@end rmacro% +{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% + +% This defines the macro itself. There are six cases: recursive and +% nonrecursive macros of zero, one, and many arguments. +% Much magic with \expandafter here. +% \xdef is used so that macro definitions will survive the file +% they're defined in; @include reads the file inside a group. +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifrecursive + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\scanmacro{\temp}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup\noexpand\scanmacro{\temp}}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{\egroup\noexpand\scanmacro{\temp}}% + \fi + \else + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname xxx\endcsname}% + \expandafter\xdef\csname\the\macname xxx\endcsname##1{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \else % many + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup\noexpand\macroargctxt + \expandafter\noexpand\csname\the\macname xx\endcsname}% + \expandafter\xdef\csname\the\macname xx\endcsname##1{% + \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname xxx\endcsname + \paramlist{% + \egroup + \noexpand\norecurse{\the\macname}% + \noexpand\scanmacro{\temp}\egroup}% + \fi + \fi} + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + +% \braceorline decides whether the next nonwhitespace character is a +% {. If so it reads up to the closing }, if not, it reads the whole +% line. Whatever was read is then fed to the next control sequence +% as an argument (by \parsebrace or \parsearg) +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup\else + \expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Just make them active and then expand them all to nothing. +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \atdummies % preserve commands, but don't expand them + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, during \shipout + }% + \fi +} + +% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +% the node name, #2 the name of the Info cross-reference, #3 the printed +% node name, #4 the name of the Info file, #5 the name of the printed +% manual. All but the node name can be omitted. +% +\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +\def\ref#1{\xrefX[#1,,,,,,,]} +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + \def\printedmanual{\ignorespaces #5}% + \def\printedrefname{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual\unskip}% + \setbox0=\hbox{\printedrefname\unskip}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1 > 0pt + % It is in another manual, so we don't have it. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + \leavevmode + \getfilename{#4}% + {\indexnofonts + \turnoffactive + % See comments at \activebackslashdouble. + {\activebackslashdouble \xdef\pdfxrefdest{#1}% + \backslashparens\pdfxrefdest}% + % + \ifnum\filenamelength>0 + \startlink attr{/Border [0 0 0]}% + goto file{\the\filename.pdf} name{\pdfxrefdest}% + \else + \startlink attr{/Border [0 0 0]}% + goto name{\pdfmkpgn{\pdfxrefdest}}% + \fi + }% + \setcolor{\linkcolor}% + \fi + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". We distinguish them by the + % LABEL-title being set to a magic string. + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd0 = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % if the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd1 > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordSection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via a macro so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi + \fi + \endlink +\endgroup} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +% If its value is nonempty, SUFFIX is output afterward. +% +\def\refx#1#2{% + {% + \indexnofonts + \otherbackslash + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + \message{\linenumber Undefined cross reference `#1'.}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Usually it's +% just a \def (we prepend XR to the control sequence name to avoid +% collisions). But if this is a float type, we have more work to do. +% +\def\xrdef#1#2{% + {% The node name might contain 8-bit characters, which in our current + % implementation are changed to commands like @'e. Don't let these + % mess up the control sequence name. + \indexnofonts + \turnoffactive + \xdef\safexrefname{#1}% + }% + % + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \catcode`\~=\other + \catcode`\[=\other + \catcode`\]=\other + \catcode`\"=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\$=\other + \catcode`\#=\other + \catcode`\&=\other + \catcode`\%=\other + \catcode`+=\other % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % Make the characters 128-255 be printing characters. + {% + \count1=128 + \def\loop{% + \catcode\count1=\other + \advance\count1 by 1 + \ifnum \count1<256 \loop \fi + }% + }% + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including footnotes. + +\newcount \footnoteno + +% The trailing space in the following definition for supereject is +% vital for proper filling; pages come out unaligned when you do a +% pagealignmacro call if that space before the closing brace is +% removed. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for info output only. +\let\footnotestyle=\comment + +{\catcode `\@=11 +% +% Auto-number footnotes. Otherwise like plain. +\gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % + % In case the footnote comes at the end of a sentence, preserve the + % extra spacing after we do the footnote number. + \let\@sf\empty + \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% Don't bother with the trickery in plain.tex to not require the +% footnote text as a parameter. Our footnotes don't need to be so general. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. + \hsize=\pagewidth + \interlinepenalty\interfootnotelinepenalty + \splittopskip\ht\strutbox % top baseline for broken footnotes + \splitmaxdepth\dp\strutbox + \floatingpenalty\@MM + \leftskip\z@skip + \rightskip\z@skip + \spaceskip\z@skip + \xspaceskip\z@skip + \parindent\defaultparindent + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\hang}% + \textindent{\thisfootno}% + % + % Don't crash into the line above the footnote text. Since this + % expands into a box, it must come within the paragraph, lest it + % provide a place where TeX can split the footnote. + \footstrut + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarily, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. + +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from ftp://tug.org/tex/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\undefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing this stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \nobreak\bigskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \line\bgroup + \fi + % + % Output the image. + \ifpdf + \dopdfimage{#1}{#2}{#3}% + \else + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \fi + % + \ifimagevmode \egroup \bigbreak \fi % space after the image +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \atdummies + % + % since we read the caption text in the macro world, where ^^M + % is turned into a normal character, we have to scan it back, so + % we don't write the literal three characters "^^M" into the aux file. + \scanexp{% + \xdef\noexpand\gtemp{% + \ifx\thisshortcaption\empty + \thiscaption + \else + \thisshortcaption + \fi + }% + }% + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + % place the captured inserts + % + % BEWARE: when the floats start floating, we have to issue warning + % whenever an insert appears inside a float which could possibly + % float. --kasal, 26may04 + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% @documentlanguage is usually given very early, just after +% @setfilename. If done too late, it may not override everything +% properly. Single argument is the language (de) or locale (de_DE) +% abbreviation. It would be nice if we could set up a hyphenation file. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{\begingroup + \let_=\normalunderscore % normal _ character for filenames + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore{#1_\finish}% + \else + \input txi-#1.tex + \fi + \closein 1 + \endgroup +\endgroup} +} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\def\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \input txi-#1.tex + \fi + \closein 1 +} +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? In the current directory +should work if nowhere else does.} + +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\parseargdef\documentencoding{% + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \setnonasciicharscatcode\active + \utfeightchardefs + % + \else + \message{Unknown document encoding #1, ignoring.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii +} + +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdef^^a0{~} + \gdef^^a1{\exclamdown} + \gdef^^a2{\missingcharmsg{CENT SIGN}} + \gdef^^a3{{\pounds}} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\missingcharmsg{YEN SIGN}} + \gdef^^a6{\missingcharmsg{BROKEN BAR}} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\copyright} + \gdef^^aa{\ordf} + \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}} + \gdef^^ac{$\lnot$} + \gdef^^ad{\-} + \gdef^^ae{\registeredsymbol} + \gdef^^af{\={}} + % + \gdef^^b0{\textdegree} + \gdef^^b1{$\pm$} + \gdef^^b2{$^2$} + \gdef^^b3{$^3$} + \gdef^^b4{\'{}} + \gdef^^b5{$\mu$} + \gdef^^b6{\P} + % + \gdef^^b7{$^.$} + \gdef^^b8{\cedilla\ } + \gdef^^b9{$^1$} + \gdef^^ba{\ordm} + % + \gdef^^bb{\missingcharmsg{RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK}} + \gdef^^bc{$1\over4$} + \gdef^^bd{$1\over2$} + \gdef^^be{$3\over4$} + \gdef^^bf{\questiondown} + % + \gdef^^c0{\`A} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\~A} + \gdef^^c4{\"A} + \gdef^^c5{\ringaccent A} + \gdef^^c6{\AE} + \gdef^^c7{\cedilla C} + \gdef^^c8{\`E} + \gdef^^c9{\'E} + \gdef^^ca{\^E} + \gdef^^cb{\"E} + \gdef^^cc{\`I} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\"I} + % + \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER ETH}} + \gdef^^d1{\~N} + \gdef^^d2{\`O} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\~O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\O} + \gdef^^d9{\`U} + \gdef^^da{\'U} + \gdef^^db{\^U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\missingcharmsg{LATIN CAPITAL LETTER THORN}} + \gdef^^df{\ss} + % + \gdef^^e0{\`a} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\~a} + \gdef^^e4{\"a} + \gdef^^e5{\ringaccent a} + \gdef^^e6{\ae} + \gdef^^e7{\cedilla c} + \gdef^^e8{\`e} + \gdef^^e9{\'e} + \gdef^^ea{\^e} + \gdef^^eb{\"e} + \gdef^^ec{\`{\dotless i}} + \gdef^^ed{\'{\dotless i}} + \gdef^^ee{\^{\dotless i}} + \gdef^^ef{\"{\dotless i}} + % + \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER ETH}} + \gdef^^f1{\~n} + \gdef^^f2{\`o} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\~o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\o} + \gdef^^f9{\`u} + \gdef^^fa{\'u} + \gdef^^fb{\^u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\missingcharmsg{LATIN SMALL LETTER THORN}} + \gdef^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdef^^a4{\euro} + \gdef^^a6{\v S} + \gdef^^a8{\v s} + \gdef^^b4{\v Z} + \gdef^^b8{\v z} + \gdef^^bc{\OE} + \gdef^^bd{\oe} + \gdef^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdef^^a0{~} + \gdef^^a1{\missingcharmsg{LATIN CAPITAL LETTER A WITH OGONEK}} + \gdef^^a2{\u{}} + \gdef^^a3{\L} + \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdef^^a5{\v L} + \gdef^^a6{\'S} + \gdef^^a7{\S} + \gdef^^a8{\"{}} + \gdef^^a9{\v S} + \gdef^^aa{\cedilla S} + \gdef^^ab{\v T} + \gdef^^ac{\'Z} + \gdef^^ad{\-} + \gdef^^ae{\v Z} + \gdef^^af{\dotaccent Z} + % + \gdef^^b0{\textdegree} + \gdef^^b1{\missingcharmsg{LATIN SMALL LETTER A WITH OGONEK}} + \gdef^^b2{\missingcharmsg{OGONEK}} + \gdef^^b3{\l} + \gdef^^b4{\'{}} + \gdef^^b5{\v l} + \gdef^^b6{\'s} + \gdef^^b7{\v{}} + \gdef^^b8{\cedilla\ } + \gdef^^b9{\v s} + \gdef^^ba{\cedilla s} + \gdef^^bb{\v t} + \gdef^^bc{\'z} + \gdef^^bd{\H{}} + \gdef^^be{\v z} + \gdef^^bf{\dotaccent z} + % + \gdef^^c0{\'R} + \gdef^^c1{\'A} + \gdef^^c2{\^A} + \gdef^^c3{\u A} + \gdef^^c4{\"A} + \gdef^^c5{\'L} + \gdef^^c6{\'C} + \gdef^^c7{\cedilla C} + \gdef^^c8{\v C} + \gdef^^c9{\'E} + \gdef^^ca{\missingcharmsg{LATIN CAPITAL LETTER E WITH OGONEK}} + \gdef^^cb{\"E} + \gdef^^cc{\v E} + \gdef^^cd{\'I} + \gdef^^ce{\^I} + \gdef^^cf{\v D} + % + \gdef^^d0{\missingcharmsg{LATIN CAPITAL LETTER D WITH STROKE}} + \gdef^^d1{\'N} + \gdef^^d2{\v N} + \gdef^^d3{\'O} + \gdef^^d4{\^O} + \gdef^^d5{\H O} + \gdef^^d6{\"O} + \gdef^^d7{$\times$} + \gdef^^d8{\v R} + \gdef^^d9{\ringaccent U} + \gdef^^da{\'U} + \gdef^^db{\H U} + \gdef^^dc{\"U} + \gdef^^dd{\'Y} + \gdef^^de{\cedilla T} + \gdef^^df{\ss} + % + \gdef^^e0{\'r} + \gdef^^e1{\'a} + \gdef^^e2{\^a} + \gdef^^e3{\u a} + \gdef^^e4{\"a} + \gdef^^e5{\'l} + \gdef^^e6{\'c} + \gdef^^e7{\cedilla c} + \gdef^^e8{\v c} + \gdef^^e9{\'e} + \gdef^^ea{\missingcharmsg{LATIN SMALL LETTER E WITH OGONEK}} + \gdef^^eb{\"e} + \gdef^^ec{\v e} + \gdef^^ed{\'\i} + \gdef^^ee{\^\i} + \gdef^^ef{\v d} + % + \gdef^^f0{\missingcharmsg{LATIN SMALL LETTER D WITH STROKE}} + \gdef^^f1{\'n} + \gdef^^f2{\v n} + \gdef^^f3{\'o} + \gdef^^f4{\^o} + \gdef^^f5{\H o} + \gdef^^f6{\"o} + \gdef^^f7{$\div$} + \gdef^^f8{\v r} + \gdef^^f9{\ringaccent u} + \gdef^^fa{\'u} + \gdef^^fb{\H u} + \gdef^^fc{\"u} + \gdef^^fd{\'y} + \gdef^^fe{\cedilla t} + \gdef^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +\begingroup + \catcode`\~13 + \catcode`\"12 + + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiTwoOctets\string~}} + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiThreeOctets\string~}} + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \xdef~{\noexpand\UTFviiiFourOctets\string~}} + \UTFviiiLoop +\endgroup + +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + + \gdef\DeclareUnicodeCharacter#1#2{% + \countUTFz = "#1\relax + \wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% + \begingroup + \parseXMLCharref + \def\UTFviiiTwoOctets##1##2{% + \csname u8:##1\string ##2\endcsname}% + \def\UTFviiiThreeOctets##1##2##3{% + \csname u8:##1\string ##2\string ##3\endcsname}% + \def\UTFviiiFourOctets##1##2##3##4{% + \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter + \gdef\UTFviiiTmp{#2}% + \endgroup} + + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctets.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% + \fi\fi\fi + } + + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz + \multiply\countUTFz by 64 + \advance\countUTFx by -\countUTFz + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +\def\utfeightchardefs{% + \DeclareUnicodeCharacter{00A0}{\tie} + \DeclareUnicodeCharacter{00A1}{\exclamdown} + \DeclareUnicodeCharacter{00A3}{\pounds} + \DeclareUnicodeCharacter{00A8}{\"{ }} + \DeclareUnicodeCharacter{00A9}{\copyright} + \DeclareUnicodeCharacter{00AA}{\ordf} + \DeclareUnicodeCharacter{00AB}{\guillemetleft} + \DeclareUnicodeCharacter{00AD}{\-} + \DeclareUnicodeCharacter{00AE}{\registeredsymbol} + \DeclareUnicodeCharacter{00AF}{\={ }} + + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} + \DeclareUnicodeCharacter{00B4}{\'{ }} + \DeclareUnicodeCharacter{00B8}{\cedilla{ }} + \DeclareUnicodeCharacter{00BA}{\ordm} + \DeclareUnicodeCharacter{00BB}{\guillemetright} + \DeclareUnicodeCharacter{00BF}{\questiondown} + + \DeclareUnicodeCharacter{00C0}{\`A} + \DeclareUnicodeCharacter{00C1}{\'A} + \DeclareUnicodeCharacter{00C2}{\^A} + \DeclareUnicodeCharacter{00C3}{\~A} + \DeclareUnicodeCharacter{00C4}{\"A} + \DeclareUnicodeCharacter{00C5}{\AA} + \DeclareUnicodeCharacter{00C6}{\AE} + \DeclareUnicodeCharacter{00C7}{\cedilla{C}} + \DeclareUnicodeCharacter{00C8}{\`E} + \DeclareUnicodeCharacter{00C9}{\'E} + \DeclareUnicodeCharacter{00CA}{\^E} + \DeclareUnicodeCharacter{00CB}{\"E} + \DeclareUnicodeCharacter{00CC}{\`I} + \DeclareUnicodeCharacter{00CD}{\'I} + \DeclareUnicodeCharacter{00CE}{\^I} + \DeclareUnicodeCharacter{00CF}{\"I} + + \DeclareUnicodeCharacter{00D1}{\~N} + \DeclareUnicodeCharacter{00D2}{\`O} + \DeclareUnicodeCharacter{00D3}{\'O} + \DeclareUnicodeCharacter{00D4}{\^O} + \DeclareUnicodeCharacter{00D5}{\~O} + \DeclareUnicodeCharacter{00D6}{\"O} + \DeclareUnicodeCharacter{00D8}{\O} + \DeclareUnicodeCharacter{00D9}{\`U} + \DeclareUnicodeCharacter{00DA}{\'U} + \DeclareUnicodeCharacter{00DB}{\^U} + \DeclareUnicodeCharacter{00DC}{\"U} + \DeclareUnicodeCharacter{00DD}{\'Y} + \DeclareUnicodeCharacter{00DF}{\ss} + + \DeclareUnicodeCharacter{00E0}{\`a} + \DeclareUnicodeCharacter{00E1}{\'a} + \DeclareUnicodeCharacter{00E2}{\^a} + \DeclareUnicodeCharacter{00E3}{\~a} + \DeclareUnicodeCharacter{00E4}{\"a} + \DeclareUnicodeCharacter{00E5}{\aa} + \DeclareUnicodeCharacter{00E6}{\ae} + \DeclareUnicodeCharacter{00E7}{\cedilla{c}} + \DeclareUnicodeCharacter{00E8}{\`e} + \DeclareUnicodeCharacter{00E9}{\'e} + \DeclareUnicodeCharacter{00EA}{\^e} + \DeclareUnicodeCharacter{00EB}{\"e} + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} + + \DeclareUnicodeCharacter{00F1}{\~n} + \DeclareUnicodeCharacter{00F2}{\`o} + \DeclareUnicodeCharacter{00F3}{\'o} + \DeclareUnicodeCharacter{00F4}{\^o} + \DeclareUnicodeCharacter{00F5}{\~o} + \DeclareUnicodeCharacter{00F6}{\"o} + \DeclareUnicodeCharacter{00F8}{\o} + \DeclareUnicodeCharacter{00F9}{\`u} + \DeclareUnicodeCharacter{00FA}{\'u} + \DeclareUnicodeCharacter{00FB}{\^u} + \DeclareUnicodeCharacter{00FC}{\"u} + \DeclareUnicodeCharacter{00FD}{\'y} + \DeclareUnicodeCharacter{00FF}{\"y} + + \DeclareUnicodeCharacter{0100}{\=A} + \DeclareUnicodeCharacter{0101}{\=a} + \DeclareUnicodeCharacter{0102}{\u{A}} + \DeclareUnicodeCharacter{0103}{\u{a}} + \DeclareUnicodeCharacter{0106}{\'C} + \DeclareUnicodeCharacter{0107}{\'c} + \DeclareUnicodeCharacter{0108}{\^C} + \DeclareUnicodeCharacter{0109}{\^c} + \DeclareUnicodeCharacter{010A}{\dotaccent{C}} + \DeclareUnicodeCharacter{010B}{\dotaccent{c}} + \DeclareUnicodeCharacter{010C}{\v{C}} + \DeclareUnicodeCharacter{010D}{\v{c}} + \DeclareUnicodeCharacter{010E}{\v{D}} + + \DeclareUnicodeCharacter{0112}{\=E} + \DeclareUnicodeCharacter{0113}{\=e} + \DeclareUnicodeCharacter{0114}{\u{E}} + \DeclareUnicodeCharacter{0115}{\u{e}} + \DeclareUnicodeCharacter{0116}{\dotaccent{E}} + \DeclareUnicodeCharacter{0117}{\dotaccent{e}} + \DeclareUnicodeCharacter{011A}{\v{E}} + \DeclareUnicodeCharacter{011B}{\v{e}} + \DeclareUnicodeCharacter{011C}{\^G} + \DeclareUnicodeCharacter{011D}{\^g} + \DeclareUnicodeCharacter{011E}{\u{G}} + \DeclareUnicodeCharacter{011F}{\u{g}} + + \DeclareUnicodeCharacter{0120}{\dotaccent{G}} + \DeclareUnicodeCharacter{0121}{\dotaccent{g}} + \DeclareUnicodeCharacter{0124}{\^H} + \DeclareUnicodeCharacter{0125}{\^h} + \DeclareUnicodeCharacter{0128}{\~I} + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} + \DeclareUnicodeCharacter{012A}{\=I} + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} + \DeclareUnicodeCharacter{012C}{\u{I}} + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} + + \DeclareUnicodeCharacter{0130}{\dotaccent{I}} + \DeclareUnicodeCharacter{0131}{\dotless{i}} + \DeclareUnicodeCharacter{0132}{IJ} + \DeclareUnicodeCharacter{0133}{ij} + \DeclareUnicodeCharacter{0134}{\^J} + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} + \DeclareUnicodeCharacter{0139}{\'L} + \DeclareUnicodeCharacter{013A}{\'l} + + \DeclareUnicodeCharacter{0141}{\L} + \DeclareUnicodeCharacter{0142}{\l} + \DeclareUnicodeCharacter{0143}{\'N} + \DeclareUnicodeCharacter{0144}{\'n} + \DeclareUnicodeCharacter{0147}{\v{N}} + \DeclareUnicodeCharacter{0148}{\v{n}} + \DeclareUnicodeCharacter{014C}{\=O} + \DeclareUnicodeCharacter{014D}{\=o} + \DeclareUnicodeCharacter{014E}{\u{O}} + \DeclareUnicodeCharacter{014F}{\u{o}} + + \DeclareUnicodeCharacter{0150}{\H{O}} + \DeclareUnicodeCharacter{0151}{\H{o}} + \DeclareUnicodeCharacter{0152}{\OE} + \DeclareUnicodeCharacter{0153}{\oe} + \DeclareUnicodeCharacter{0154}{\'R} + \DeclareUnicodeCharacter{0155}{\'r} + \DeclareUnicodeCharacter{0158}{\v{R}} + \DeclareUnicodeCharacter{0159}{\v{r}} + \DeclareUnicodeCharacter{015A}{\'S} + \DeclareUnicodeCharacter{015B}{\'s} + \DeclareUnicodeCharacter{015C}{\^S} + \DeclareUnicodeCharacter{015D}{\^s} + \DeclareUnicodeCharacter{015E}{\cedilla{S}} + \DeclareUnicodeCharacter{015F}{\cedilla{s}} + + \DeclareUnicodeCharacter{0160}{\v{S}} + \DeclareUnicodeCharacter{0161}{\v{s}} + \DeclareUnicodeCharacter{0162}{\cedilla{t}} + \DeclareUnicodeCharacter{0163}{\cedilla{T}} + \DeclareUnicodeCharacter{0164}{\v{T}} + + \DeclareUnicodeCharacter{0168}{\~U} + \DeclareUnicodeCharacter{0169}{\~u} + \DeclareUnicodeCharacter{016A}{\=U} + \DeclareUnicodeCharacter{016B}{\=u} + \DeclareUnicodeCharacter{016C}{\u{U}} + \DeclareUnicodeCharacter{016D}{\u{u}} + \DeclareUnicodeCharacter{016E}{\ringaccent{U}} + \DeclareUnicodeCharacter{016F}{\ringaccent{u}} + + \DeclareUnicodeCharacter{0170}{\H{U}} + \DeclareUnicodeCharacter{0171}{\H{u}} + \DeclareUnicodeCharacter{0174}{\^W} + \DeclareUnicodeCharacter{0175}{\^w} + \DeclareUnicodeCharacter{0176}{\^Y} + \DeclareUnicodeCharacter{0177}{\^y} + \DeclareUnicodeCharacter{0178}{\"Y} + \DeclareUnicodeCharacter{0179}{\'Z} + \DeclareUnicodeCharacter{017A}{\'z} + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} + \DeclareUnicodeCharacter{017C}{\dotaccent{z}} + \DeclareUnicodeCharacter{017D}{\v{Z}} + \DeclareUnicodeCharacter{017E}{\v{z}} + + \DeclareUnicodeCharacter{01C4}{D\v{Z}} + \DeclareUnicodeCharacter{01C5}{D\v{z}} + \DeclareUnicodeCharacter{01C6}{d\v{z}} + \DeclareUnicodeCharacter{01C7}{LJ} + \DeclareUnicodeCharacter{01C8}{Lj} + \DeclareUnicodeCharacter{01C9}{lj} + \DeclareUnicodeCharacter{01CA}{NJ} + \DeclareUnicodeCharacter{01CB}{Nj} + \DeclareUnicodeCharacter{01CC}{nj} + \DeclareUnicodeCharacter{01CD}{\v{A}} + \DeclareUnicodeCharacter{01CE}{\v{a}} + \DeclareUnicodeCharacter{01CF}{\v{I}} + + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} + \DeclareUnicodeCharacter{01D1}{\v{O}} + \DeclareUnicodeCharacter{01D2}{\v{o}} + \DeclareUnicodeCharacter{01D3}{\v{U}} + \DeclareUnicodeCharacter{01D4}{\v{u}} + + \DeclareUnicodeCharacter{01E2}{\={\AE}} + \DeclareUnicodeCharacter{01E3}{\={\ae}} + \DeclareUnicodeCharacter{01E6}{\v{G}} + \DeclareUnicodeCharacter{01E7}{\v{g}} + \DeclareUnicodeCharacter{01E8}{\v{K}} + \DeclareUnicodeCharacter{01E9}{\v{k}} + + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} + \DeclareUnicodeCharacter{01F1}{DZ} + \DeclareUnicodeCharacter{01F2}{Dz} + \DeclareUnicodeCharacter{01F3}{dz} + \DeclareUnicodeCharacter{01F4}{\'G} + \DeclareUnicodeCharacter{01F5}{\'g} + \DeclareUnicodeCharacter{01F8}{\`N} + \DeclareUnicodeCharacter{01F9}{\`n} + \DeclareUnicodeCharacter{01FC}{\'{\AE}} + \DeclareUnicodeCharacter{01FD}{\'{\ae}} + \DeclareUnicodeCharacter{01FE}{\'{\O}} + \DeclareUnicodeCharacter{01FF}{\'{\o}} + + \DeclareUnicodeCharacter{021E}{\v{H}} + \DeclareUnicodeCharacter{021F}{\v{h}} + + \DeclareUnicodeCharacter{0226}{\dotaccent{A}} + \DeclareUnicodeCharacter{0227}{\dotaccent{a}} + \DeclareUnicodeCharacter{0228}{\cedilla{E}} + \DeclareUnicodeCharacter{0229}{\cedilla{e}} + \DeclareUnicodeCharacter{022E}{\dotaccent{O}} + \DeclareUnicodeCharacter{022F}{\dotaccent{o}} + + \DeclareUnicodeCharacter{0232}{\=Y} + \DeclareUnicodeCharacter{0233}{\=y} + \DeclareUnicodeCharacter{0237}{\dotless{j}} + + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} + + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} + + \DeclareUnicodeCharacter{1E20}{\=G} + \DeclareUnicodeCharacter{1E21}{\=g} + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} + \DeclareUnicodeCharacter{1E26}{\"H} + \DeclareUnicodeCharacter{1E27}{\"h} + + \DeclareUnicodeCharacter{1E30}{\'K} + \DeclareUnicodeCharacter{1E31}{\'k} + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} + \DeclareUnicodeCharacter{1E3E}{\'M} + \DeclareUnicodeCharacter{1E3F}{\'m} + + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} + + \DeclareUnicodeCharacter{1E54}{\'P} + \DeclareUnicodeCharacter{1E55}{\'p} + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} + + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} + + \DeclareUnicodeCharacter{1E7C}{\~V} + \DeclareUnicodeCharacter{1E7D}{\~v} + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} + + \DeclareUnicodeCharacter{1E80}{\`W} + \DeclareUnicodeCharacter{1E81}{\`w} + \DeclareUnicodeCharacter{1E82}{\'W} + \DeclareUnicodeCharacter{1E83}{\'w} + \DeclareUnicodeCharacter{1E84}{\"W} + \DeclareUnicodeCharacter{1E85}{\"w} + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} + \DeclareUnicodeCharacter{1E8C}{\"X} + \DeclareUnicodeCharacter{1E8D}{\"x} + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} + + \DeclareUnicodeCharacter{1E90}{\^Z} + \DeclareUnicodeCharacter{1E91}{\^z} + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} + \DeclareUnicodeCharacter{1E97}{\"t} + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} + + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} + + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} + \DeclareUnicodeCharacter{1EBC}{\~E} + \DeclareUnicodeCharacter{1EBD}{\~e} + + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} + + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} + + \DeclareUnicodeCharacter{1EF2}{\`Y} + \DeclareUnicodeCharacter{1EF3}{\`y} + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} + + \DeclareUnicodeCharacter{1EF8}{\~Y} + \DeclareUnicodeCharacter{1EF9}{\~y} + + \DeclareUnicodeCharacter{2013}{--} + \DeclareUnicodeCharacter{2014}{---} + \DeclareUnicodeCharacter{2018}{\quoteleft} + \DeclareUnicodeCharacter{2019}{\quoteright} + \DeclareUnicodeCharacter{201A}{\quotesinglbase} + \DeclareUnicodeCharacter{201C}{\quotedblleft} + \DeclareUnicodeCharacter{201D}{\quotedblright} + \DeclareUnicodeCharacter{201E}{\quotedblbase} + \DeclareUnicodeCharacter{2022}{\bullet} + \DeclareUnicodeCharacter{2026}{\dots} + \DeclareUnicodeCharacter{2039}{\guilsinglleft} + \DeclareUnicodeCharacter{203A}{\guilsinglright} + \DeclareUnicodeCharacter{20AC}{\euro} + + \DeclareUnicodeCharacter{2192}{\expansion} + \DeclareUnicodeCharacter{21D2}{\result} + + \DeclareUnicodeCharacter{2212}{\minus} + \DeclareUnicodeCharacter{2217}{\point} + \DeclareUnicodeCharacter{2261}{\equiv} +}% end of \utfeightchardefs + + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be so finicky about underfull hboxes, either. +\hbadness = 2000 + +% Following George Bush, get rid of widows and orphans. +\widowpenalty=10000 +\clubpenalty=10000 + +% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +% using an old version of TeX, don't do anything. We want the amount of +% stretch added to depend on the line length, hence the dependence on +% \hsize. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \pageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \pagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \hfuzz = 1pt + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \hfuzz = 1.2pt + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + + +\message{and turning on texinfo input format.} + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other +\catcode`\~=\other +\catcode`\^=\other +\catcode`\_=\other +\catcode`\|=\other +\catcode`\<=\other +\catcode`\>=\other +\catcode`\+=\other +\catcode`\$=\other +\def\normaldoublequote{"} +\def\normaltilde{~} +\def\normalcaret{^} +\def\normalunderscore{_} +\def\normalverticalbar{|} +\def\normalless{<} +\def\normalgreater{>} +\def\normalplus{+} +\def\normaldollar{$}%$ font-lock fix + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), and another way in other fonts, +% where something hairier probably needs to be done. +% +% #1 is what to print if we are indeed using \tt; #2 is what to print +% otherwise. Since all the Computer Modern typewriter fonts have zero +% interword stretch (and shrink), and it is reasonable to expect all +% typewriter fonts to have this, we can check that font parameter. +% +\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Turn off all special characters except @ +% (and those which the user can use as if they were ordinary). +% Most of these we simply print from the \tt font, but for some, we can +% use math or other variants that look better in normal text. + +\catcode`\"=\active +\def\activedoublequote{{\tt\char34}} +\let"=\activedoublequote +\catcode`\~=\active +\def~{{\tt\char126}} +\chardef\hat=`\^ +\catcode`\^=\active +\def^{{\tt \hat}} + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\let\realunder=_ +% Subroutine for the previous macro. +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } + +\catcode`\|=\active +\def|{{\tt\char124}} +\chardef \less=`\< +\catcode`\<=\active +\def<{{\tt \less}} +\chardef \gtr=`\> +\catcode`\>=\active +\def>{{\tt \gtr}} +\catcode`\+=\active +\def+{{\tt \char 43}} +\catcode`\$=\active +\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active +@def@normalbackslash{{@tt@backslashcurfont}} +% On startup, @fixbackslash assigns: +% @let \ = @normalbackslash + +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. +% +@def@normalturnoffactive{% + @let\=@normalbackslash + @let"=@normaldoublequote + @let~=@normaltilde + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let<=@normalless + @let>=@normalgreater + @let+=@normalplus + @let$=@normaldollar %$ font-lock fix + @unsepspaces +} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + +% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +% That is what \eatinput is for; after that, the `\' should revert to printing +% a backslash. +% +@gdef@eatinput input texinfo{@fixbackslash} +@global@let\ = @eatinput + +% On the other hand, perhaps the file did not have a `\input texinfo'. Then +% the first `\' in the file would cause an error. This macro tries to fix +% that, assuming it is called before the first `\' could plausibly occur. +% Also turn back on active characters that might appear in the input +% file name, in case not using a pre-dumped format. +% +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active + @catcode`@_=@active +} + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These look ok in all fonts, so just make them not special. +@catcode`@& = @other +@catcode`@# = @other +@catcode`@% = @other + + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@ignore + arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 +@end ignore diff --git a/font/font.c b/font/font.c new file mode 100644 index 0000000..cfe1ee4 --- /dev/null +++ b/font/font.c @@ -0,0 +1,1026 @@ +/* font.c - Font API and font file loader. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef FONT_DEBUG +#define FONT_DEBUG 0 +#endif + +struct char_index_entry +{ + grub_uint32_t code; + grub_uint8_t storage_flags; + grub_uint32_t offset; + + /* Glyph if loaded, or NULL otherwise. */ + struct grub_font_glyph *glyph; +}; + +#define FONT_WEIGHT_NORMAL 100 +#define FONT_WEIGHT_BOLD 200 + +struct grub_font +{ + char *name; + grub_file_t file; + char *family; + short point_size; + short weight; + short max_char_width; + short max_char_height; + short ascent; + short descent; + short leading; + grub_uint32_t num_chars; + struct char_index_entry *char_index; +}; + +/* Definition of font registry. */ +struct grub_font_node *grub_font_list; + +static int register_font (grub_font_t font); +static void font_init (grub_font_t font); +static void free_font (grub_font_t font); +static void remove_font (grub_font_t font); + +struct font_file_section +{ + /* The file this section is in. */ + grub_file_t file; + + /* FOURCC name of the section. */ + char name[4]; + + /* Length of the section contents. */ + grub_uint32_t length; + + /* Set by open_section() on EOF. */ + int eof; +}; + +/* Font file format constants. */ +static const char pff2_magic[4] = { 'P', 'F', 'F', '2' }; +static const char section_names_file[4] = { 'F', 'I', 'L', 'E' }; +static const char section_names_font_name[4] = { 'N', 'A', 'M', 'E' }; +static const char section_names_point_size[4] = { 'P', 'T', 'S', 'Z' }; +static const char section_names_weight[4] = { 'W', 'E', 'I', 'G' }; +static const char section_names_max_char_width[4] = { 'M', 'A', 'X', 'W' }; +static const char section_names_max_char_height[4] = { 'M', 'A', 'X', 'H' }; +static const char section_names_ascent[4] = { 'A', 'S', 'C', 'E' }; +static const char section_names_descent[4] = { 'D', 'E', 'S', 'C' }; +static const char section_names_char_index[4] = { 'C', 'H', 'I', 'X' }; +static const char section_names_data[4] = { 'D', 'A', 'T', 'A' }; + +/* Replace unknown glyphs with a rounded question mark. */ +static grub_uint8_t unknown_glyph_bitmap[] = +{ + /* 76543210 */ + 0x7C, /* ooooo */ + 0x82, /* o o */ + 0xBA, /* o ooo o */ + 0xAA, /* o o o o */ + 0xAA, /* o o o o */ + 0x8A, /* o o o */ + 0x9A, /* o oo o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x7C, /* ooooo */ + 0x00 /* */ +}; + +/* The "unknown glyph" glyph, used as a last resort. */ +static struct grub_font_glyph *unknown_glyph; + +/* The font structure used when no other font is loaded. This functions + as a "Null Object" pattern, so that code everywhere does not have to + check for a NULL grub_font_t to avoid dereferencing a null pointer. */ +static struct grub_font null_font; + +/* Flag to ensure module is initialized only once. */ +static grub_uint8_t font_loader_initialized; + +void +grub_font_loader_init (void) +{ + /* Only initialize font loader once. */ + if (font_loader_initialized) + return; + + /* Make glyph for unknown glyph. */ + unknown_glyph = grub_malloc(sizeof(struct grub_font_glyph) + + sizeof(unknown_glyph_bitmap)); + if (! unknown_glyph) + return; + + unknown_glyph->width = 8; + unknown_glyph->height = 16; + unknown_glyph->offset_x = 0; + unknown_glyph->offset_y = -3; + unknown_glyph->device_width = 8; + grub_memcpy(unknown_glyph->bitmap, + unknown_glyph_bitmap, sizeof(unknown_glyph_bitmap)); + + /* Initialize the null font. */ + font_init (&null_font); + null_font.name = ""; + null_font.ascent = unknown_glyph->height-3; + null_font.descent = 3; + null_font.max_char_width = unknown_glyph->width; + null_font.max_char_height = unknown_glyph->height; + + font_loader_initialized = 1; +} + +/* Initialize the font object with initial default values. */ +static void +font_init (grub_font_t font) +{ + font->name = 0; + font->file = 0; + font->family = 0; + font->point_size = 0; + font->weight = 0; + + /* Default leading value, not in font file yet. */ + font->leading = 1; + + font->max_char_width = 0; + font->max_char_height = 0; + font->ascent = 0; + font->descent = 0; + font->num_chars = 0; + font->char_index = 0; +} + +/* Open the next section in the file. + + On success, the section name is stored in section->name and the length in + section->length, and 0 is returned. On failure, 1 is returned and + grub_errno is set approriately with an error message. + + If 1 is returned due to being at the end of the file, then section->eof is + set to 1; otherwise, section->eof is set to 0. */ +static int +open_section (grub_file_t file, struct font_file_section *section) +{ + grub_ssize_t retval; + grub_uint32_t raw_length; + + section->file = file; + section->eof = 0; + + /* Read the FOURCC section name. */ + retval = grub_file_read (file, section->name, 4); + if (retval >= 0 && retval < 4) + { + /* EOF encountered. */ + section->eof = 1; + return 1; + } + else if (retval < 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font format error: can't read section name"); + return 1; + } + + /* Read the big-endian 32-bit section length. */ + retval = grub_file_read (file, (char *) &raw_length, 4); + if (retval >= 0 && retval < 4) + { + /* EOF encountered. */ + section->eof = 1; + return 1; + } + else if (retval < 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font format error: can't read section length"); + return 1; + } + + /* Convert byte-order and store in *length. */ + section->length = grub_be_to_cpu32 (raw_length); + + return 0; +} + +/* Size in bytes of each character index (CHIX section) + entry in the font file. */ +#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4) + +/* Load the character index (CHIX) section contents from the font file. This + presumes that the position of FILE is positioned immediately after the + section length for the CHIX section (i.e., at the start of the section + contents). Returns 0 upon success, nonzero for failure (in which case + grub_errno is set appropriately). */ +static int +load_font_index (grub_file_t file, grub_uint32_t sect_length, struct + grub_font *font) +{ + unsigned i; + +#if FONT_DEBUG >= 2 + grub_printf("load_font_index(sect_length=%d)\n", sect_length); +#endif + + /* Sanity check: ensure section length is divisible by the entry size. */ + if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font file format error: character index length %d " + "is not a multiple of the entry size %d", + sect_length, FONT_CHAR_INDEX_ENTRY_SIZE); + return 1; + } + + /* Calculate the number of characters. */ + font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE; + + /* Allocate the character index array. */ + font->char_index = grub_malloc (font->num_chars + * sizeof (struct char_index_entry)); + if (! font->char_index) + return 1; + +#if FONT_DEBUG >= 2 + grub_printf("num_chars=%d)\n", font->num_chars); +#endif + + /* Load the character index data from the file. */ + for (i = 0; i < font->num_chars; i++) + { + struct char_index_entry *entry = &font->char_index[i]; + + /* Read code point value; convert to native byte order. */ + if (grub_file_read (file, (char *) &entry->code, 4) != 4) + return 1; + entry->code = grub_be_to_cpu32 (entry->code); + + /* Read storage flags byte. */ + if (grub_file_read (file, (char *) &entry->storage_flags, 1) != 1) + return 1; + + /* Read glyph data offset; convert to native byte order. */ + if (grub_file_read (file, (char *) &entry->offset, 4) != 4) + return 1; + entry->offset = grub_be_to_cpu32 (entry->offset); + + /* No glyph loaded. Will be loaded on demand and cached thereafter. */ + entry->glyph = 0; + +#if FONT_DEBUG >= 5 + /* Print the 1st 10 characters. */ + if (i < 10) + grub_printf("c=%d o=%d\n", entry->code, entry->offset); +#endif + } + + return 0; +} + +/* Read the contents of the specified section as a string, which is + allocated on the heap. Returns 0 if there is an error. */ +static char * +read_section_as_string (struct font_file_section *section) +{ + char *str; + grub_ssize_t ret; + + str = grub_malloc (section->length + 1); + if (! str) + return 0; + + ret = grub_file_read (section->file, str, section->length); + if (ret < 0 || ret != (grub_ssize_t) section->length) + { + grub_free (str); + return 0; + } + + str[section->length] = '\0'; + return str; +} + +/* Read the contents of the current section as a 16-bit integer value, + which is stored into *VALUE. + Returns 0 upon success, nonzero upon failure. */ +static int +read_section_as_short (struct font_file_section *section, grub_int16_t *value) +{ + grub_uint16_t raw_value; + + if (section->length != 2) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font file format error: section %c%c%c%c length " + "is %d but should be 2", + section->name[0], section->name[1], + section->name[2], section->name[3], + section->length); + return 1; + } + if (grub_file_read (section->file, (char *) &raw_value, 2) != 2) + return 1; + + *value = grub_be_to_cpu16 (raw_value); + return 0; +} + +/* Load a font and add it to the beginning of the global font list. + Returns 0 upon success, nonzero upon failure. */ +int +grub_font_load (const char *filename) +{ + grub_file_t file = 0; + struct font_file_section section; + char magic[4]; + grub_font_t font = 0; + +#if FONT_DEBUG >= 1 + grub_printf("add_font(%s)\n", filename); +#endif + + file = grub_buffile_open (filename, 1024); + if (!file) + goto fail; + +#if FONT_DEBUG >= 3 + grub_printf("file opened\n"); +#endif + + /* Read the FILE section. It indicates the file format. */ + if (open_section (file, §ion) != 0) + goto fail; + +#if FONT_DEBUG >= 3 + grub_printf("opened FILE section\n"); +#endif + if (grub_memcmp (section.name, section_names_file, 4) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font file format error: 1st section must be FILE"); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_printf("section name ok\n"); +#endif + if (section.length != 4) + { + grub_error (GRUB_ERR_BAD_FONT, + "Font file format error (file type ID length is %d " + "but should be 4)", section.length); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_printf("section length ok\n"); +#endif + /* Check the file format type code. */ + if (grub_file_read (file, magic, 4) != 4) + goto fail; + +#if FONT_DEBUG >= 3 + grub_printf("read magic ok\n"); +#endif + + if (grub_memcmp (magic, pff2_magic, 4) != 0) + { + grub_error (GRUB_ERR_BAD_FONT, "Invalid font magic %x %x %x %x", + magic[0], magic[1], magic[2], magic[3]); + goto fail; + } + +#if FONT_DEBUG >= 3 + grub_printf("compare magic ok\n"); +#endif + + /* Allocate the font object. */ + font = (grub_font_t) grub_malloc (sizeof (struct grub_font)); + if (! font) + goto fail; + + font_init (font); + font->file = file; + +#if FONT_DEBUG >= 3 + grub_printf("allocate font ok; loading font info\n"); +#endif + + /* Load the font information. */ + while (1) + { + if (open_section (file, §ion) != 0) + { + if (section.eof) + break; /* Done reading the font file. */ + else + goto fail; + } + +#if FONT_DEBUG >= 2 + grub_printf("opened section %c%c%c%c ok\n", + section.name[0], section.name[1], + section.name[2], section.name[3]); +#endif + + if (grub_memcmp (section.name, section_names_font_name, 4) == 0) + { + font->name = read_section_as_string (§ion); + if (!font->name) + goto fail; + } + else if (grub_memcmp (section.name, section_names_point_size, 4) == 0) + { + if (read_section_as_short (§ion, &font->point_size) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_weight, 4) == 0) + { + char *wt; + wt = read_section_as_string (§ion); + if (!wt) + continue; + /* Convert the weight string 'normal' or 'bold' into a number. */ + if (grub_strcmp (wt, "normal") == 0) + font->weight = FONT_WEIGHT_NORMAL; + else if (grub_strcmp (wt, "bold") == 0) + font->weight = FONT_WEIGHT_BOLD; + grub_free (wt); + } + else if (grub_memcmp (section.name, section_names_max_char_width, 4) == 0) + { + if (read_section_as_short (§ion, &font->max_char_width) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_max_char_height, 4) == 0) + { + if (read_section_as_short (§ion, &font->max_char_height) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_ascent, 4) == 0) + { + if (read_section_as_short (§ion, &font->ascent) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_descent, 4) == 0) + { + if (read_section_as_short (§ion, &font->descent) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_char_index, 4) == 0) + { + if (load_font_index (file, section.length, font) != 0) + goto fail; + } + else if (grub_memcmp (section.name, section_names_data, 4) == 0) + { + /* When the DATA section marker is reached, we stop reading. */ + break; + } + else + { + /* Unhandled section type, simply skip past it. */ +#if FONT_DEBUG >= 3 + grub_printf("Unhandled section type, skipping.\n"); +#endif + grub_off_t section_end = grub_file_tell (file) + section.length; + if ((int) grub_file_seek (file, section_end) == -1) + goto fail; + } + } + + if (! font->name) + { + grub_printf ("Note: Font has no name.\n"); + font->name = grub_strdup ("Unknown"); + } + +#if FONT_DEBUG >= 1 + grub_printf ("Loaded font `%s'.\n" + "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n", + font->name, + font->ascent, font->descent, + font->max_char_width, font->max_char_height, + font->num_chars); +#endif + + if (font->max_char_width == 0 + || font->max_char_height == 0 + || font->num_chars == 0 + || font->char_index == 0 + || font->ascent == 0 + || font->descent == 0) + { + grub_error (GRUB_ERR_BAD_FONT, + "Invalid font file: missing some required data."); + goto fail; + } + + /* Add the font to the global font registry. */ + if (register_font (font) != 0) + goto fail; + + return 0; + +fail: + free_font (font); + return 1; +} + +/* Read a 16-bit big-endian integer from FILE, convert it to native byte + order, and store it in *VALUE. + Returns 0 on success, 1 on failure. */ +static int +read_be_uint16 (grub_file_t file, grub_uint16_t * value) +{ + if (grub_file_read (file, (char *) value, 2) != 2) + return 1; + *value = grub_be_to_cpu16 (*value); + return 0; +} + +static int +read_be_int16 (grub_file_t file, grub_int16_t * value) +{ + /* For the signed integer version, use the same code as for unsigned. */ + return read_be_uint16 (file, (grub_uint16_t *) value); +} + +/* Return a pointer to the character index entry for the glyph corresponding to + the codepoint CODE in the font FONT. If not found, return zero. */ +static struct char_index_entry * +find_glyph (const grub_font_t font, grub_uint32_t code) +{ + grub_uint32_t i; + grub_uint32_t len = font->num_chars; + struct char_index_entry *table = font->char_index; + + /* Do a linear search. */ + for (i = 0; i < len; i++) + { + if (table[i].code == code) + return &table[i]; + } + + return 0; +} + +/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded + from the font file if has not been loaded yet. + Returns a pointer to the glyph if found, or 0 if it is not found. */ +static struct grub_font_glyph * +grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) +{ + struct char_index_entry *index_entry; + + index_entry = find_glyph (font, code); + if (index_entry) + { + struct grub_font_glyph *glyph = 0; + grub_uint16_t width; + grub_uint16_t height; + grub_int16_t xoff; + grub_int16_t yoff; + grub_int16_t dwidth; + int len; + + if (index_entry->glyph) + /* Return cached glyph. */ + return index_entry->glyph; + + if (! font->file) + /* No open file, can't load any glyphs. */ + return 0; + + /* Make sure we can find glyphs for error messages. Push active + error message to error stack and reset error message. */ + grub_error_push (); + + grub_file_seek (font->file, index_entry->offset); + + /* Read the glyph width, height, and baseline. */ + if (read_be_uint16(font->file, &width) != 0 + || read_be_uint16(font->file, &height) != 0 + || read_be_int16(font->file, &xoff) != 0 + || read_be_int16(font->file, &yoff) != 0 + || read_be_int16(font->file, &dwidth) != 0) + { + remove_font (font); + return 0; + } + + len = (width * height + 7) / 8; + glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); + if (! glyph) + { + remove_font (font); + return 0; + } + + glyph->font = font; + glyph->width = width; + glyph->height = height; + glyph->offset_x = xoff; + glyph->offset_y = yoff; + glyph->device_width = dwidth; + + /* Don't try to read empty bitmaps (e.g., space characters). */ + if (len != 0) + { + if (grub_file_read (font->file, (char *) glyph->bitmap, len) != len) + { + remove_font (font); + return 0; + } + } + + /* Restore old error message. */ + grub_error_pop (); + + /* Cache the glyph. */ + index_entry->glyph = glyph; + + return glyph; + } + + return 0; +} + +/* Free the memory used by FONT. + This should not be called if the font has been made available to + users (once it is added to the global font list), since there would + be the possibility of a dangling pointer. */ +static void +free_font (grub_font_t font) +{ + if (font) + { + if (font->file) + grub_file_close (font->file); + grub_free (font->name); + grub_free (font->family); + grub_free (font->char_index); + grub_free (font); + } +} + +/* Add FONT to the global font registry. + Returns 0 upon success, nonzero on failure + (the font was not registered). */ +static int +register_font (grub_font_t font) +{ + struct grub_font_node *node = 0; + + node = grub_malloc (sizeof (struct grub_font_node)); + if (! node) + return 1; + + node->value = font; + node->next = grub_font_list; + grub_font_list = node; + + return 0; +} + +/* Remove the font from the global font list. We don't actually free the + font's memory since users could be holding references to the font. */ +static void +remove_font (grub_font_t font) +{ + struct grub_font_node **nextp, *cur; + + for (nextp = &grub_font_list, cur = *nextp; + cur; + nextp = &cur->next, cur = cur->next) + { + if (cur->value == font) + { + *nextp = cur->next; + + /* Free the node, but not the font itself. */ + grub_free (cur); + + return; + } + } +} + +/* Get a font from the list of loaded fonts. This function will return + another font if the requested font is not available. If no fonts are + loaded, then a special 'null font' is returned, which contains no glyphs, + but is not a null pointer so the caller may omit checks for NULL. */ +grub_font_t +grub_font_get (const char *font_name) +{ + struct grub_font_node *node; + + for (node = grub_font_list; node; node = node->next) + { + grub_font_t font = node->value; + if (grub_strcmp (font->name, font_name) == 0) + return font; + } + + /* If no font by that name is found, return the first font in the list + as a fallback. */ + if (grub_font_list && grub_font_list->value) + return grub_font_list->value; + else + /* The null_font is a last resort. */ + return &null_font; +} + +/* Get the full name of the font. For instance, "Helvetica Bold 12". */ +const char * +grub_font_get_name (grub_font_t font) +{ + return font->name; +} + +/* Get the maximum width of any character in the font in pixels. */ +int +grub_font_get_max_char_width (grub_font_t font) +{ + return font->max_char_width; +} + +/* Get the maximum height of any character in the font in pixels. */ +int +grub_font_get_max_char_height (grub_font_t font) +{ + return font->max_char_height; +} + +/* Get the distance in pixels from the top of characters to the baseline. */ +int +grub_font_get_ascent (grub_font_t font) +{ + return font->ascent; +} + +/* Get the distance in pixels from the baseline to the lowest descenders + (for instance, in a lowercase 'y', 'g', etc.). */ +int +grub_font_get_descent (grub_font_t font) +{ + return font->descent; +} + +/* Get the *standard leading* of the font in pixel, which is the spacing + between two lines of text. Specifically, it is the space between the + descent of one line and the ascent of the next line. This is included + in the *height* metric. */ +int +grub_font_get_leading (grub_font_t font) +{ + return font->leading; +} + +/* Get the distance in pixels between baselines of adjacent lines of text. */ +int +grub_font_get_height (grub_font_t font) +{ + return font->ascent + font->descent + font->leading; +} + +/* Get the width in pixels of the specified UTF-8 string, when rendered in + in the specified font (but falling back on other fonts for glyphs that + are missing). */ +int +grub_font_get_string_width (grub_font_t font, const char *str) +{ + int width; + struct grub_font_glyph *glyph; + grub_uint32_t code; + const grub_uint8_t *ptr; + + for (ptr = (const grub_uint8_t *) str, width = 0; + grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) + { + glyph = grub_font_get_glyph_with_fallback (font, code); + width += glyph->device_width; + } + + return width; +} + +/* Get the glyph for FONT corresponding to the Unicode code point CODE. + Returns a pointer to an glyph indicating there is no glyph available + if CODE does not exist in the font. The glyphs are cached once loaded. */ +struct grub_font_glyph * +grub_font_get_glyph (grub_font_t font, grub_uint32_t code) +{ + struct grub_font_glyph *glyph; + glyph = grub_font_get_glyph_internal (font, code); + if (glyph == 0) + glyph = unknown_glyph; + return glyph; +} + + +/* Calculate a subject value representing "how similar" two fonts are. + This is used to prioritize the order that fonts are scanned for missing + glyphs. The object is to select glyphs from the most similar font + possible, for the best appearance. + The heuristic is crude, but it helps greatly when fonts of similar + sizes are used so that tiny 8 point glyphs are not mixed into a string + of 24 point text unless there is no other choice. */ +static int +get_font_diversity(grub_font_t a, grub_font_t b) +{ + int d; + + d = 0; + + if (a->ascent && b->ascent) + d += grub_abs (a->ascent - b->ascent) * 8; + else + /* Penalty for missing attributes. */ + d += 50; + + if (a->max_char_height && b->max_char_height) + d += grub_abs (a->max_char_height - b->max_char_height) * 8; + else + /* Penalty for missing attributes. */ + d += 50; + + /* Weight is a minor factor. */ + d += (a->weight != b->weight) ? 5 : 0; + + return d; +} + +/* Get a glyph corresponding to the codepoint CODE. If FONT contains the + specified glyph, then it is returned. Otherwise, all other loaded fonts + are searched until one is found that contains a glyph for CODE. + If no glyph is available for CODE in the loaded fonts, then a glyph + representing an unknown character is returned. + This function never returns NULL. + The returned glyph is owned by the font manager and should not be freed + by the caller. The glyphs are cached. */ +struct grub_font_glyph * +grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) +{ + struct grub_font_glyph *glyph; + struct grub_font_node *node; + /* Keep track of next node, in case there's an I/O error in + grub_font_get_glyph_internal() and the font is removed from the list. */ + struct grub_font_node *next; + /* Information on the best glyph found so far, to help find the glyph in + the best matching to the requested one. */ + int best_diversity; + struct grub_font_glyph *best_glyph; + + if (font) + { + /* First try to get the glyph from the specified font. */ + glyph = grub_font_get_glyph_internal (font, code); + if (glyph) + return glyph; + } + + /* Otherwise, search all loaded fonts for the glyph and use the one from + the font that best matches the requested font. */ + best_diversity = 10000; + best_glyph = 0; + + for (node = grub_font_list; node; node = next) + { + grub_font_t curfont; + + curfont = node->value; + next = node->next; + + glyph = grub_font_get_glyph_internal (curfont, code); + if (glyph) + { + int d; + + d = get_font_diversity (curfont, font); + if (d < best_diversity) + { + best_diversity = d; + best_glyph = glyph; + } + } + } + + if (best_glyph) + return best_glyph; + else + /* Glyph not available in any font. Return unknown glyph. */ + return unknown_glyph; +} + + +/* Draw the specified glyph at (x, y). The y coordinate designates the + baseline of the character, while the x coordinate designates the left + side location of the character. */ +grub_err_t +grub_font_draw_glyph (struct grub_font_glyph *glyph, + grub_video_color_t color, + int left_x, int baseline_y) +{ + struct grub_video_bitmap glyph_bitmap; + + /* Don't try to draw empty glyphs (U+0020, etc.). */ + if (glyph->width == 0 || glyph->height == 0) + return GRUB_ERR_NONE; + + glyph_bitmap.mode_info.width = glyph->width; + glyph_bitmap.mode_info.height = glyph->height; + glyph_bitmap.mode_info.mode_type = + (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) + | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; + glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED; + glyph_bitmap.mode_info.bpp = 1; + + /* Really 1 bit per pixel. */ + glyph_bitmap.mode_info.bytes_per_pixel = 0; + + /* Packed densely as bits. */ + glyph_bitmap.mode_info.pitch = glyph->width; + + glyph_bitmap.mode_info.number_of_colors = 2; + glyph_bitmap.mode_info.bg_red = 0; + glyph_bitmap.mode_info.bg_green = 0; + glyph_bitmap.mode_info.bg_blue = 0; + glyph_bitmap.mode_info.bg_alpha = 0; + grub_video_unmap_color(color, + &glyph_bitmap.mode_info.fg_red, + &glyph_bitmap.mode_info.fg_green, + &glyph_bitmap.mode_info.fg_blue, + &glyph_bitmap.mode_info.fg_alpha); + glyph_bitmap.data = glyph->bitmap; + + int bitmap_left = left_x + glyph->offset_x; + int bitmap_bottom = baseline_y - glyph->offset_y; + int bitmap_top = bitmap_bottom - glyph->height; + + return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND, + bitmap_left, bitmap_top, + 0, 0, + glyph->width, glyph->height); +} + +/* Draw a UTF-8 string of text on the current video render target. + The x coordinate specifies the starting x position for the first character, + while the y coordinate specifies the baseline position. + If the string contains a character that FONT does not contain, then + a glyph from another loaded font may be used instead. */ +grub_err_t +grub_font_draw_string (const char *str, grub_font_t font, + grub_video_color_t color, + int left_x, int baseline_y) +{ + int x; + struct grub_font_glyph *glyph; + grub_uint32_t code; + const grub_uint8_t *ptr; + + for (ptr = (const grub_uint8_t *) str, x = left_x; + grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) + { + glyph = grub_font_get_glyph_with_fallback (font, code); + if (grub_font_draw_glyph (glyph, color, x, baseline_y) + != GRUB_ERR_NONE) + return grub_errno; + x += glyph->device_width; + } + + return GRUB_ERR_NONE; +} + diff --git a/font/font_cmd.c b/font/font_cmd.c new file mode 100644 index 0000000..6cbae5b --- /dev/null +++ b/font/font_cmd.c @@ -0,0 +1,77 @@ +/* font_cmd.c - Font command definition. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +loadfont_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, + char **args) +{ + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified"); + + while (argc--) + if (grub_font_load (*args++) != 0) + return GRUB_ERR_BAD_FONT; + + return GRUB_ERR_NONE; +} + +static grub_err_t +lsfonts_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_font_node *node; + + grub_printf ("Loaded fonts:\n"); + for (node = grub_font_list; node; node = node->next) + { + grub_font_t font = node->value; + grub_printf ("%s\n", grub_font_get_name (font)); + } + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(font_manager) +{ + grub_font_loader_init (); + + grub_register_command ("loadfont", loadfont_command, GRUB_COMMAND_FLAG_BOTH, + "loadfont FILE...", + "Specify one or more font files to load.", 0); + + grub_register_command ("lsfonts", lsfonts_command, GRUB_COMMAND_FLAG_BOTH, + "lsfonts", + "List the loaded fonts.", 0); +} + +GRUB_MOD_FINI(font_manager) +{ + /* TODO: Determine way to free allocated resources. + Warning: possible pointer references could be in use. */ + + grub_unregister_command ("loadfont"); +} + diff --git a/fs/affs.c b/fs/affs.c new file mode 100644 index 0000000..bc7bc21 --- /dev/null +++ b/fs/affs.c @@ -0,0 +1,570 @@ +/* affs.c - Amiga Fast FileSystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* The affs bootblock. */ +struct grub_affs_bblock +{ + grub_uint8_t type[3]; + grub_uint8_t flags; + grub_uint32_t checksum; + grub_uint32_t rootblock; +} __attribute__ ((packed)); + +/* Set if the filesystem is a AFFS filesystem. Otherwise this is an + OFS filesystem. */ +#define GRUB_AFFS_FLAG_FFS 1 + +/* The affs rootblock. */ +struct grub_affs_rblock +{ + grub_uint8_t type[4]; + grub_uint8_t unused1[8]; + grub_uint32_t htsize; + grub_uint32_t unused2; + grub_uint32_t checksum; + grub_uint32_t hashtable[1]; +} __attribute__ ((packed)); + +/* The second part of a file header block. */ +struct grub_affs_file +{ + grub_uint8_t unused1[12]; + grub_uint32_t size; + grub_uint8_t unused2[104]; + grub_uint8_t namelen; + grub_uint8_t name[30]; + grub_uint8_t unused3[33]; + grub_uint32_t next; + grub_uint32_t parent; + grub_uint32_t extension; + grub_int32_t type; +} __attribute__ ((packed)); + +/* The location of `struct grub_affs_file' relative to the end of a + file header block. */ +#define GRUB_AFFS_FILE_LOCATION 200 + +/* The offset in both the rootblock and the file header block for the + hashtable, symlink and block pointers (all synonyms). */ +#define GRUB_AFFS_HASHTABLE_OFFSET 24 +#define GRUB_AFFS_BLOCKPTR_OFFSET 24 +#define GRUB_AFFS_SYMLINK_OFFSET 24 + +#define GRUB_AFFS_SYMLINK_SIZE(blocksize) ((blocksize) - 225) + +#define GRUB_AFFS_FILETYPE_DIR -3 +#define GRUB_AFFS_FILETYPE_REG 2 +#define GRUB_AFFS_FILETYPE_SYMLINK 3 + + +struct grub_fshelp_node +{ + struct grub_affs_data *data; + int block; + int size; + int parent; +}; + +/* Information about a "mounted" affs filesystem. */ +struct grub_affs_data +{ + struct grub_affs_bblock bblock; + struct grub_fshelp_node diropen; + grub_disk_t disk; + + /* Blocksize in sectors. */ + int blocksize; + + /* The number of entries in the hashtable. */ + int htsize; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +static grub_disk_addr_t +grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + int links; + grub_uint32_t pos; + int block = node->block; + struct grub_affs_file file; + struct grub_affs_data *data = node->data; + grub_uint32_t mod; + + /* Find the block that points to the fileblock we are looking up by + following the chain until the right table is reached. */ + for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--) + { + grub_disk_read (data->disk, block + data->blocksize - 1, + data->blocksize * (GRUB_DISK_SECTOR_SIZE + - GRUB_AFFS_FILE_LOCATION), + sizeof (file), (char *) &file); + if (grub_errno) + return 0; + + block = grub_be_to_cpu32 (file.extension); + } + + /* Translate the fileblock to the block within the right table. */ + fileblock = mod; + grub_disk_read (data->disk, block, + GRUB_AFFS_BLOCKPTR_OFFSET + + (data->htsize - fileblock - 1) * sizeof (pos), + sizeof (pos), (char *) &pos); + if (grub_errno) + return 0; + + return grub_be_to_cpu32 (pos); +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_affs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_affs_read_block, + node->size, 0); +} + + +static struct grub_affs_data * +grub_affs_mount (grub_disk_t disk) +{ + struct grub_affs_data *data; + grub_uint32_t *rootblock = 0; + struct grub_affs_rblock *rblock; + + int checksum = 0; + int checksumr = 0; + int blocksize = 0; + + data = grub_malloc (sizeof (struct grub_affs_data)); + if (!data) + return 0; + + /* Read the bootblock. */ + grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock), + (char *) &data->bblock); + if (grub_errno) + goto fail; + + /* Make sure this is an affs filesystem. */ + if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3)) + { + grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem"); + goto fail; + } + + /* Test if the filesystem is a OFS filesystem. */ + if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS)) + { + grub_error (GRUB_ERR_BAD_FS, "ofs not yet supported"); + goto fail; + } + + /* Read the bootblock. */ + grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock), + (char *) &data->bblock); + if (grub_errno) + goto fail; + + /* No sane person uses more than 8KB for a block. At least I hope + for that person because in that case this won't work. */ + rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE * 16); + if (!rootblock) + goto fail; + + rblock = (struct grub_affs_rblock *) rootblock; + + /* Read the rootblock. */ + grub_disk_read (disk, (disk->total_sectors >> 1) + blocksize, 0, + GRUB_DISK_SECTOR_SIZE * 16, (char *) rootblock); + if (grub_errno) + goto fail; + + /* The filesystem blocksize is not stored anywhere in the filesystem + itself. One way to determine it is reading blocks for the + rootblock until the checksum is correct. */ + checksumr = grub_be_to_cpu32 (rblock->checksum); + rblock->checksum = 0; + for (blocksize = 0; blocksize < 8; blocksize++) + { + grub_uint32_t *currblock = rootblock + GRUB_DISK_SECTOR_SIZE * blocksize; + unsigned int i; + + for (i = 0; i < GRUB_DISK_SECTOR_SIZE / sizeof (*currblock); i++) + checksum += grub_be_to_cpu32 (currblock[i]); + + if (checksumr == -checksum) + break; + } + if (-checksum != checksumr) + { + grub_error (GRUB_ERR_BAD_FS, "affs blocksize could not be determined"); + goto fail; + } + blocksize++; + + data->blocksize = blocksize; + data->disk = disk; + data->htsize = grub_be_to_cpu32 (rblock->htsize); + data->diropen.data = data; + data->diropen.block = (disk->total_sectors >> 1); + + grub_free (rootblock); + + return data; + + fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem"); + + grub_free (data); + grub_free (rootblock); + return 0; +} + + +static char * +grub_affs_read_symlink (grub_fshelp_node_t node) +{ + struct grub_affs_data *data = node->data; + char *symlink; + + symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize)); + if (!symlink) + return 0; + + grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET, + GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + grub_printf ("Symlink: `%s'\n", symlink); + return symlink; +} + + +static int +grub_affs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + int i; + struct grub_affs_file file; + struct grub_fshelp_node *node = 0; + struct grub_affs_data *data = dir->data; + grub_uint32_t *hashtable; + + auto int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, + int size, int type); + + int NESTED_FUNC_ATTR grub_affs_create_node (const char *name, int block, + int size, int type) + { + node = grub_malloc (sizeof (*node)); + if (!node) + { + grub_free (hashtable); + return 1; + } + + node->data = data; + node->size = size; + node->block = block; + node->parent = grub_be_to_cpu32 (file.parent); + + if (hook (name, type, node)) + { + grub_free (hashtable); + return 1; + } + return 0; + } + + hashtable = grub_malloc (data->htsize * sizeof (*hashtable)); + if (!hashtable) + return 1; + + grub_disk_read (data->disk, dir->block, GRUB_AFFS_HASHTABLE_OFFSET, + data->htsize * sizeof (*hashtable), (char *) hashtable); + if (grub_errno) + goto fail; + + /* Create the directory entries for `.' and `..'. */ + if (grub_affs_create_node (".", dir->block, dir->size, GRUB_FSHELP_DIR)) + return 1; + if (grub_affs_create_node ("..", dir->parent ? dir->parent : dir->block, + dir->size, GRUB_FSHELP_DIR)) + return 1; + + for (i = 0; i < data->htsize; i++) + { + enum grub_fshelp_filetype type; + grub_uint64_t next; + + if (!hashtable[i]) + continue; + + /* Every entry in the hashtable can be chained. Read the entire + chain. */ + next = grub_be_to_cpu32 (hashtable[i]); + + while (next) + { + grub_disk_read (data->disk, next + data->blocksize - 1, + data->blocksize * GRUB_DISK_SECTOR_SIZE + - GRUB_AFFS_FILE_LOCATION, + sizeof (file), (char *) &file); + if (grub_errno) + goto fail; + + file.name[file.namelen] = '\0'; + + if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR) + type = GRUB_FSHELP_REG; + else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_REG) + type = GRUB_FSHELP_DIR; + else if (grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else + type = GRUB_FSHELP_UNKNOWN; + + if (grub_affs_create_node ((char *) (file.name), next, + grub_be_to_cpu32 (file.size), type)) + return 1; + + next = grub_be_to_cpu32 (file.next); + } + } + + grub_free (hashtable); + return 0; + + fail: + grub_free (node); + grub_free (hashtable); + return 0; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_affs_open (struct grub_file *file, const char *name) +{ + struct grub_affs_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_affs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir, + grub_affs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + file->size = fdiro->size; + data->diropen = *fdiro; + grub_free (fdiro); + + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (data && fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_affs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_affs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_affs_data *data = + (struct grub_affs_data *) file->data; + + int size = grub_affs_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); + + return size; +} + + +static grub_err_t +grub_affs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_affs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_affs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir, + grub_affs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_affs_iterate_dir (fdiro, iterate); + + fail: + if (data && fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_affs_label (grub_device_t device, char **label) +{ + struct grub_affs_data *data; + struct grub_affs_file file; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_affs_mount (disk); + if (data) + { + /* The rootblock maps quite well on a file header block, it's + something we can use here. */ + grub_disk_read (data->disk, disk->total_sectors >> 1, + data->blocksize * (GRUB_DISK_SECTOR_SIZE + - GRUB_AFFS_FILE_LOCATION), + sizeof (file), (char *) &file); + if (grub_errno) + return 0; + + *label = grub_strndup ((char *) (file.name), file.namelen); + } + else + *label = 0; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + + +static struct grub_fs grub_affs_fs = + { + .name = "affs", + .dir = grub_affs_dir, + .open = grub_affs_open, + .read = grub_affs_read, + .close = grub_affs_close, + .label = grub_affs_label, + .next = 0 + }; + +GRUB_MOD_INIT(affs) +{ + grub_fs_register (&grub_affs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(affs) +{ + grub_fs_unregister (&grub_affs_fs); +} diff --git a/fs/afs.c b/fs/afs.c new file mode 100644 index 0000000..3f7efa7 --- /dev/null +++ b/fs/afs.c @@ -0,0 +1,636 @@ +/* afs.c - The native AtheOS file-system. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_AFS_DIRECT_BLOCK_COUNT 12 +#define GRUB_AFS_BLOCKS_PER_DI_RUN 4 + +#define GRUB_AFS_SBLOCK_MAGIC1 0x41465331 /* AFS1 */ +#define GRUB_AFS_SBLOCK_MAGIC2 0xdd121031 +#define GRUB_AFS_SBLOCK_MAGIC3 0x15b6830e + +#define GRUB_AFS_INODE_MAGIC 0x64358428 + +#define GRUB_AFS_BTREE_MAGIC 0x65768995 + +#define GRUB_AFS_BNODE_SIZE 1024 + +#define GRUB_AFS_S_IFMT 00170000 +#define GRUB_AFS_S_IFLNK 0120000 + +#define GRUB_AFS_S_IFREG 0100000 +#define GRUB_AFS_S_IFDIR 0040000 +#define GRUB_AFS_S_IFIFO 0010000 + +#define GRUB_AFS_NULL_VAL ((grub_afs_bvalue_t)-1) + +#define U16(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \ + grub_le_to_cpu16 (u) : grub_be_to_cpu16 (u)) + +#define U32(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \ + grub_le_to_cpu32 (u) : grub_be_to_cpu32 (u)) + +#define U64(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \ + grub_le_to_cpu64 (u) : grub_be_to_cpu64 (u)) + +#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \ + ((char *) (node) + \ + sizeof (struct grub_afs_bnode) + \ + ((node->key_size + 3) & ~3))) + +#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \ + ((char *) B_KEY_INDEX_OFFSET (node) + \ + node->key_count * 2)) + +enum +{ + GRUB_AFS_BO_LITTLE_ENDIAN, + GRUB_AFS_BO_BIG_ENDIAN +}; + +typedef grub_uint64_t grub_afs_off_t; +typedef grub_uint64_t grub_afs_bigtime; +typedef grub_uint64_t grub_afs_bvalue_t; + +struct grub_afs_blockrun +{ + grub_uint32_t group; + grub_uint16_t start; + grub_uint16_t len; +}; + +struct grub_afs_datastream +{ + struct grub_afs_blockrun direct[GRUB_AFS_DIRECT_BLOCK_COUNT]; + grub_afs_off_t max_direct_range; + struct grub_afs_blockrun indirect; + grub_afs_off_t max_indirect_range; + struct grub_afs_blockrun double_indirect; + grub_afs_off_t max_double_indirect_range; + grub_afs_off_t size; +}; + +struct grub_afs_bnode +{ + grub_afs_bvalue_t left; + grub_afs_bvalue_t right; + grub_afs_bvalue_t overflow; + grub_uint32_t key_count; + grub_uint32_t key_size; + char key_data[0]; +}; + +struct grub_afs_btree +{ + grub_uint32_t magic; + grub_afs_bvalue_t root; + grub_uint32_t tree_depth; + grub_afs_bvalue_t last_node; + grub_afs_bvalue_t first_free; +} ; + +struct grub_afs_sblock +{ + grub_uint8_t name[32]; + grub_uint32_t magic1; + grub_uint32_t byte_order; + grub_uint32_t block_size; + grub_uint32_t block_shift; + grub_afs_off_t num_blocks; + grub_afs_off_t used_blocks; + grub_uint32_t inode_size; + grub_uint32_t magic2; + grub_uint32_t block_per_group; // Number of blocks per allocation group (Max 65536) + grub_uint32_t alloc_group_shift; // Number of bits to shift a group number to get a byte address. + grub_uint32_t alloc_group_count; + grub_uint32_t flags; + struct grub_afs_blockrun log_block; + grub_afs_off_t log_start; + grub_uint32_t valid_log_blocks; + grub_uint32_t log_size; + grub_uint32_t magic3; + struct grub_afs_blockrun root_dir; // Root dir inode. + struct grub_afs_blockrun deleted_files; // Directory containing files scheduled for deletion. + struct grub_afs_blockrun index_dir; // Directory of index files. + grub_uint32_t boot_loader_size; + grub_uint32_t pad[7]; +}; + +struct grub_afs_inode +{ + grub_uint32_t magic1; + struct grub_afs_blockrun inode_num; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t mode; + grub_uint32_t flags; + grub_uint32_t link_count; + grub_afs_bigtime create_time; + grub_afs_bigtime modified_time; + struct grub_afs_blockrun parent; + struct grub_afs_blockrun attrib_dir; + grub_uint32_t index_type; /* Key data-key only used for index files */ + grub_uint32_t inode_size; + void* vnode; + struct grub_afs_datastream stream; + grub_uint32_t pad[4]; + grub_uint32_t small_data[1]; +}; + +struct grub_fshelp_node +{ + struct grub_afs_data *data; + struct grub_afs_inode inode; +}; + +struct grub_afs_data +{ + grub_disk_t disk; + struct grub_afs_sblock sblock; + struct grub_afs_inode *inode; + struct grub_fshelp_node diropen; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static grub_afs_off_t +grub_afs_run_to_num (struct grub_afs_sblock *sb, + struct grub_afs_blockrun *run) +{ + return ((grub_afs_off_t) U32 (sb, run->group) * sb->block_per_group + + U16 (sb, run->start)); +} + +static grub_err_t +grub_afs_read_inode (struct grub_afs_data *data, + grub_uint32_t ino, struct grub_afs_inode *inode) +{ + return grub_disk_read (data->disk, + ino * + (data->sblock.block_size >> GRUB_DISK_SECTOR_BITS), + 0, sizeof (struct grub_afs_inode), + (char *) inode); +} + +static grub_disk_addr_t +grub_afs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_afs_sblock *sb = &node->data->sblock; + struct grub_afs_datastream *ds = &node->inode.stream; + + if (fileblock < U64 (sb, ds->max_direct_range)) + { + int i; + + for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++) + { + if (fileblock < U16 (sb, ds->direct[i].len)) + return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock; + fileblock -= U16 (sb, ds->direct[i].len); + } + } + else if (fileblock < U64 (sb, ds->max_indirect_range)) + { + int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + struct grub_afs_blockrun indir[ptrs_per_blk]; + grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect); + int i; + + fileblock -= U64 (sb, ds->max_direct_range); + for (i = 0; i < ds->indirect.len; i++, blk++) + { + int j; + + if (grub_disk_read (node->data->disk, + blk * (sb->block_size >> GRUB_DISK_SECTOR_BITS), + 0, sizeof (indir), + (char *) indir)) + return 0; + + for (j = 0; j < ptrs_per_blk; j++) + { + if (fileblock < U16 (sb, indir[j].len)) + return grub_afs_run_to_num (sb, &indir[j]) + fileblock; + + fileblock -= U16 (sb, indir[j].len); + } + } + } + else + { + int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun); + struct grub_afs_blockrun indir[ptrs_per_blk]; + + /* ([idblk][idptr]) ([dblk][dptr]) [blk] */ + int cur_pos = fileblock - U64 (sb, ds->max_indirect_range); + + int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN; + int dblk_size = dptr_size * ptrs_per_blk; + int idptr_size = dblk_size * GRUB_AFS_BLOCKS_PER_DI_RUN; + int idblk_size = idptr_size * ptrs_per_blk; + + int off = cur_pos % GRUB_AFS_BLOCKS_PER_DI_RUN; + int dptr = (cur_pos / dptr_size) % ptrs_per_blk; + int dblk = (cur_pos / dblk_size) % GRUB_AFS_BLOCKS_PER_DI_RUN; + int idptr = (cur_pos / idptr_size) % ptrs_per_blk; + int idblk = (cur_pos / idblk_size); + + if (grub_disk_read (node->data->disk, + (grub_afs_run_to_num (sb, &ds->double_indirect) + + idblk) * + (sb->block_size >> GRUB_DISK_SECTOR_BITS), + 0, sizeof (indir), + (char *) indir)) + return 0; + + if (grub_disk_read (node->data->disk, + (grub_afs_run_to_num (sb, &indir[idptr]) + dblk) * + (sb->block_size >> GRUB_DISK_SECTOR_BITS), + 0, sizeof (indir), + (char *) indir)) + return 0; + + return grub_afs_run_to_num (sb, &indir[dptr]) + off; + } + + return 0; +} + +static grub_ssize_t +grub_afs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_afs_read_block, + U64 (&node->data->sblock, + node->inode.stream.size), + node->data->sblock.block_shift + - GRUB_DISK_SECTOR_BITS); +} + +static int +grub_afs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + struct grub_afs_btree head; + char node_data [GRUB_AFS_BNODE_SIZE]; + struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data; + struct grub_afs_sblock *sb = &dir->data->sblock; + int i; + + if ((! dir->inode.stream.size) || + ((U32 (sb, dir->inode.mode) & GRUB_AFS_S_IFMT) != GRUB_AFS_S_IFDIR)) + return 0; + + grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head); + if (grub_errno) + return 0; + + grub_afs_read_file (dir, 0, U64 (sb, head.root), + GRUB_AFS_BNODE_SIZE, (char *) node); + if (grub_errno) + return 0; + + for (i = 0; i < (int) U32 (sb, head.tree_depth) - 1; i++) + { + grub_afs_bvalue_t blk; + + blk = U64(sb, B_KEY_VALUE_OFFSET (node) [0]); + grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node); + if (grub_errno) + return 0; + } + + if (node->key_count) + { + grub_uint32_t cur_key = 0; + + while (1) + { + int key_start, key_size; + grub_uint16_t *index; + + index = B_KEY_INDEX_OFFSET (node); + + key_start = U16 (sb, (cur_key > 0) ? index[cur_key - 1] : 0); + key_size = U16 (sb, index[cur_key]) - key_start; + if (key_size) + { + char filename [key_size + 1]; + struct grub_fshelp_node *fdiro; + int mode, type; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (! fdiro) + return 0; + + fdiro->data = dir->data; + if (grub_afs_read_inode (dir->data, + U64 (sb, B_KEY_VALUE_OFFSET (node) [cur_key]), + &fdiro->inode)) + return 0; + + grub_memcpy (filename, &node->key_data[key_start], key_size); + filename [key_size] = 0; + + mode = (U32 (sb, fdiro->inode.mode) & GRUB_AFS_S_IFMT); + if (mode == GRUB_AFS_S_IFDIR) + type = GRUB_FSHELP_DIR; + else if (mode == GRUB_AFS_S_IFREG) + type = GRUB_FSHELP_REG; + else + type = GRUB_FSHELP_UNKNOWN; + + if (hook (filename, type, fdiro)) + return 1; + } + + cur_key++; + if (cur_key >= U32 (sb, node->key_count)) + { + if (node->right == GRUB_AFS_NULL_VAL) + break; + + grub_afs_read_file (dir, 0, U64 (sb, node->right), + GRUB_AFS_BNODE_SIZE, (char *) node); + if (grub_errno) + return 0; + + cur_key = 0; + } + } + } + + return 0; +} + +static int +grub_afs_validate_sblock (struct grub_afs_sblock *sb) +{ + if (grub_le_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1) + { + if (grub_le_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_LITTLE_ENDIAN) + return 0; + + sb->byte_order = GRUB_AFS_BO_LITTLE_ENDIAN; + sb->magic2 = grub_le_to_cpu32 (sb->magic2); + sb->magic3 = grub_le_to_cpu32 (sb->magic3); + sb->block_shift = grub_le_to_cpu32 (sb->block_shift); + sb->block_size = grub_le_to_cpu32 (sb->block_size); + sb->used_blocks = grub_le_to_cpu64 (sb->used_blocks); + sb->num_blocks = grub_le_to_cpu64 (sb->num_blocks); + sb->inode_size = grub_le_to_cpu32 (sb->inode_size); + sb->alloc_group_count = grub_le_to_cpu32 (sb->alloc_group_count); + sb->alloc_group_shift = grub_le_to_cpu32 (sb->alloc_group_shift); + sb->block_per_group = grub_le_to_cpu32 (sb->block_per_group); + sb->alloc_group_count = grub_le_to_cpu32 (sb->alloc_group_count); + sb->log_size = grub_le_to_cpu32 (sb->log_size); + } + else if (grub_be_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1) + { + if (grub_be_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_BIG_ENDIAN) + return 0; + + sb->byte_order = GRUB_AFS_BO_BIG_ENDIAN; + sb->magic2 = grub_be_to_cpu32 (sb->magic2); + sb->magic3 = grub_be_to_cpu32 (sb->magic3); + sb->block_shift = grub_be_to_cpu32 (sb->block_shift); + sb->block_size = grub_be_to_cpu32 (sb->block_size); + sb->used_blocks = grub_be_to_cpu64 (sb->used_blocks); + sb->num_blocks = grub_be_to_cpu64 (sb->num_blocks); + sb->inode_size = grub_be_to_cpu32 (sb->inode_size); + sb->alloc_group_count = grub_be_to_cpu32 (sb->alloc_group_count); + sb->alloc_group_shift = grub_be_to_cpu32 (sb->alloc_group_shift); + sb->block_per_group = grub_be_to_cpu32 (sb->block_per_group); + sb->alloc_group_count = grub_be_to_cpu32 (sb->alloc_group_count); + sb->log_size = grub_be_to_cpu32 (sb->log_size); + } + else + return 0; + + if ((sb->magic2 != GRUB_AFS_SBLOCK_MAGIC2) || + (sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3)) + return 0; + + if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size) || + (sb->used_blocks > sb->num_blocks ) || + (sb->inode_size != sb->block_size) || + (0 == sb->block_size) || + ((grub_uint32_t) (1 << sb->alloc_group_shift) != + sb->block_per_group * sb->block_size) || + (sb->alloc_group_count * sb->block_per_group < sb->num_blocks) || + (U16 (sb, sb->log_block.len) != sb->log_size) || + (U32 (sb, sb->valid_log_blocks) > sb->log_size)) + return 0; + + return 1; +} + +static struct grub_afs_data * +grub_afs_mount (grub_disk_t disk) +{ + struct grub_afs_data *data = 0; + + data = grub_malloc (sizeof (struct grub_afs_data)); + if (!data) + return 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_afs_sblock), + (char *) &data->sblock)) + goto fail; + + if (! grub_afs_validate_sblock (&data->sblock)) + { + if (grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_afs_sblock), + (char *) &data->sblock)) + goto fail; + + if (! grub_afs_validate_sblock (&data->sblock)) + goto fail; + } + + data->diropen.data = data; + data->inode = &data->diropen.inode; + data->disk = disk; + + if (grub_afs_read_inode (data, + grub_afs_run_to_num (&data->sblock, + &data->sblock.root_dir), + data->inode)) + goto fail; + + return data; + +fail: + grub_error (GRUB_ERR_BAD_FS, "not an afs filesystem"); + grub_free (data); + return 0; +} + +static grub_err_t +grub_afs_open (struct grub_file *file, const char *name) +{ + struct grub_afs_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_afs_mount (file->device->disk); + if (! data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_afs_iterate_dir, + 0, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode)); + grub_free (fdiro); + + file->size = U64 (&data->sblock, data->inode->stream.size); + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_ssize_t +grub_afs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_afs_data *data = (struct grub_afs_data *) file->data; + + return grub_afs_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + +static grub_err_t +grub_afs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_afs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_afs_data *data = 0;; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_afs_mount (device->disk); + if (! data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_afs_iterate_dir, + 0, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_afs_iterate_dir (fdiro, iterate); + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static struct grub_fs grub_afs_fs = { + .name = "afs", + .dir = grub_afs_dir, + .open = grub_afs_open, + .read = grub_afs_read, + .close = grub_afs_close, + .label = 0, + .next = 0 +}; + +GRUB_MOD_INIT (afs) +{ + grub_fs_register (&grub_afs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI (afs) +{ + grub_fs_unregister (&grub_afs_fs); +} diff --git a/fs/cpio.c b/fs/cpio.c new file mode 100644 index 0000000..3d8078a --- /dev/null +++ b/fs/cpio.c @@ -0,0 +1,380 @@ +/* cpio.c - cpio and tar filesystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#define MAGIC_BCPIO 070707 + +struct HEAD_BCPIO +{ + grub_uint16_t magic; + grub_uint16_t dev; + grub_uint16_t ino; + grub_uint16_t mode; + grub_uint16_t uid; + grub_uint16_t gid; + grub_uint16_t nlink; + grub_uint16_t rdev; + grub_uint16_t mtime_1; + grub_uint16_t mtime_2; + grub_uint16_t namesize; + grub_uint16_t filesize_1; + grub_uint16_t filesize_2; +} __attribute__ ((packed)); + +#define MAGIC_USTAR "ustar" + +struct HEAD_USTAR +{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char typeflag; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; +} __attribute__ ((packed)); + +#define HEAD_LENG sizeof(struct HEAD_USTAR) + +struct grub_cpio_data +{ + grub_disk_t disk; + grub_uint32_t hofs; + grub_uint32_t dofs; + grub_uint32_t size; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static grub_err_t +grub_cpio_find_file (struct grub_cpio_data *data, char **name, + grub_uint32_t * ofs) +{ +#ifndef MODE_USTAR + struct HEAD_BCPIO hd; + + if (grub_disk_read + (data->disk, 0, data->hofs, sizeof (hd), (char *) &hd)) + return grub_errno; + + if (hd.magic != MAGIC_BCPIO) + return grub_error (GRUB_ERR_BAD_FS, "Invalid cpio archive"); + + data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; + + if (hd.namesize & 1) + hd.namesize++; + + if ((*name = grub_malloc (hd.namesize)) == NULL) + return grub_errno; + + if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd), + hd.namesize, *name)) + { + grub_free (*name); + return grub_errno; + } + + if (data->size == 0 && hd.mode == 0 && hd.namesize == 11 + 1 + && ! grub_memcmp(*name, "TRAILER!!!", 11)) + { + *ofs = 0; + return GRUB_ERR_NONE; + } + + data->dofs = data->hofs + sizeof (hd) + hd.namesize; + *ofs = data->dofs + data->size; + if (data->size & 1) + (*ofs)++; +#else + struct HEAD_USTAR hd; + + if (grub_disk_read + (data->disk, 0, data->hofs, sizeof (hd), (char *) &hd)) + return grub_errno; + + if (!hd.name[0]) + { + *ofs = 0; + return GRUB_ERR_NONE; + } + + if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) + return grub_error (GRUB_ERR_BAD_FS, "Invalid tar archive"); + + if ((*name = grub_strdup (hd.name)) == NULL) + return grub_errno; + + data->size = grub_strtoul (hd.size, NULL, 8); + data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; + *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & + ~(GRUB_DISK_SECTOR_SIZE - 1)); +#endif + return GRUB_ERR_NONE; +} + +static struct grub_cpio_data * +grub_cpio_mount (grub_disk_t disk) +{ + char hd[HEAD_LENG]; + struct grub_cpio_data *data; + + if (grub_disk_read (disk, 0, 0, sizeof (hd), hd)) + goto fail; + +#ifndef MODE_USTAR + if (((struct HEAD_BCPIO *) hd)->magic != MAGIC_BCPIO) +#else + if (grub_memcmp (((struct HEAD_USTAR *) hd)->magic, MAGIC_USTAR, + sizeof (MAGIC_USTAR) - 1)) +#endif + goto fail; + + data = (struct grub_cpio_data *) grub_malloc (sizeof (*data)); + if (!data) + goto fail; + + data->disk = disk; + + return data; + +fail: + grub_error (GRUB_ERR_BAD_FS, "not a " +#ifdef MODE_USTAR + "tar" +#else + "cpio" +#endif + " filesystem"); + return 0; +} + +static grub_err_t +grub_cpio_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_cpio_data *data; + grub_uint32_t ofs; + char *prev, *name; + const char *np; + int len; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + prev = 0; + + data = grub_cpio_mount (device->disk); + if (!data) + goto fail; + + np = path + 1; + len = grub_strlen (path) - 1; + + data->hofs = 0; + while (1) + { + if (grub_cpio_find_file (data, &name, &ofs)) + goto fail; + + if (!ofs) + break; + + if (grub_memcmp (np, name, len) == 0) + { + char *p, *n; + + n = name + len; + if (*n == '/') + n++; + + p = grub_strchr (name + len, '/'); + if (p) + *p = 0; + + if ((!prev) || (grub_strcmp (prev, name) != 0)) + { + hook (name + len, p != NULL); + if (prev) + grub_free (prev); + prev = name; + } + else + grub_free (name); + } + data->hofs = ofs; + } + +fail: + + if (prev) + grub_free (prev); + + if (data) + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_cpio_open (grub_file_t file, const char *name) +{ + struct grub_cpio_data *data; + grub_uint32_t ofs; + char *fn; + int i, j; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_cpio_mount (file->device->disk); + if (!data) + goto fail; + + data->hofs = 0; + while (1) + { + if (grub_cpio_find_file (data, &fn, &ofs)) + goto fail; + + if (!ofs) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + break; + } + + /* Compare NAME and FN by hand in order to cope with duplicate + slashes. */ + i = 1; + j = 0; + while (1) + { + if (name[i] != fn[j]) + goto no_match; + + if (name[i] == '\0') + break; + + if (name[i] == '/' && name[i+1] == '/') + i++; + + i++; + j++; + } + + file->data = data; + file->size = data->size; + grub_free (fn); + + return GRUB_ERR_NONE; + + no_match: + + grub_free (fn); + data->hofs = ofs; + } + +fail: + + if (data) + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_ssize_t +grub_cpio_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_cpio_data *data; + + data = file->data; + return (grub_disk_read (data->disk, 0, data->dofs + file->offset, + len, buf)) ? -1 : (grub_ssize_t) len; +} + +static grub_err_t +grub_cpio_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static struct grub_fs grub_cpio_fs = { +#ifdef MODE_USTAR + .name = "tarfs", +#else + .name = "cpiofs", +#endif + .dir = grub_cpio_dir, + .open = grub_cpio_open, + .read = grub_cpio_read, + .close = grub_cpio_close, +}; + +#ifdef MODE_USTAR +GRUB_MOD_INIT (cpio) +#else +GRUB_MOD_INIT (tar) +#endif +{ + grub_fs_register (&grub_cpio_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +#ifdef MODE_USTAR +GRUB_MOD_FINI (cpio) +#else +GRUB_MOD_FINI (tar) +#endif +{ + grub_fs_unregister (&grub_cpio_fs); +} diff --git a/fs/ext2.c b/fs/ext2.c new file mode 100644 index 0000000..ac0757e --- /dev/null +++ b/fs/ext2.c @@ -0,0 +1,922 @@ +/* ext2.c - Second Extended filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* Magic value used to identify an ext2 filesystem. */ +#define EXT2_MAGIC 0xEF53 +/* Amount of indirect blocks in an inode. */ +#define INDIRECT_BLOCKS 12 +/* Maximum length of a pathname. */ +#define EXT2_PATH_MAX 4096 +/* Maximum nesting of symlinks, used to prevent a loop. */ +#define EXT2_MAX_SYMLINKCNT 8 + +/* The good old revision and the default inode size. */ +#define EXT2_GOOD_OLD_REVISION 0 +#define EXT2_GOOD_OLD_INODE_SIZE 128 + +/* Filetype used in directory entry. */ +#define FILETYPE_UNKNOWN 0 +#define FILETYPE_REG 1 +#define FILETYPE_DIRECTORY 2 +#define FILETYPE_SYMLINK 7 + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Log2 size of ext2 block in 512 blocks. */ +#define LOG2_EXT2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.log2_block_size) + 1) + +/* Log2 size of ext2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.log2_block_size) + 10) + +/* The size of an ext2 block in bytes. */ +#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE (data)) + +/* The revision level. */ +#define EXT2_REVISION(data) grub_le_to_cpu32 (data->sblock.revision_level) + +/* The inode size. */ +#define EXT2_INODE_SIZE(data) \ + (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \ + ? EXT2_GOOD_OLD_INODE_SIZE \ + : grub_le_to_cpu16 (data->sblock.inode_size)) + +/* Superblock filesystem feature flags (RW compatible) + * A filesystem with any of these enabled can be read and written by a driver + * that does not understand them without causing metadata/data corruption. */ +#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 +#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 +#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +/* Superblock filesystem feature flags (RO compatible) + * A filesystem with any of these enabled can be safely read by a driver that + * does not understand them, but should not be written to, usually because + * additional metadata is required. */ +#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 +/* Superblock filesystem feature flags (back-incompatible) + * A filesystem with any of these enabled should not be attempted to be read + * by a driver that does not understand them, since they usually indicate + * metadata format changes that might confuse the reader. */ +#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 +#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Volume is journal device */ +#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* Extents used */ +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 + +/* The set of back-incompatible features this driver DOES support. Add (OR) + * flags here as the related features are implemented into the driver. */ +#define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \ + | EXT4_FEATURE_INCOMPAT_EXTENTS \ + | EXT4_FEATURE_INCOMPAT_FLEX_BG ) +/* List of rationales for the ignored "incompatible" features: + * needs_recovery: Not really back-incompatible - was added as such to forbid + * ext2 drivers from mounting an ext3 volume with a dirty + * journal because they will ignore the journal, but the next + * ext3 driver to mount the volume will find the journal and + * replay it, potentially corrupting the metadata written by + * the ext2 drivers. Safe to ignore for this RO driver. */ +#define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER ) + + +#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U + +#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1 +#define EXT3_JOURNAL_COMMIT_BLOCK 2 +#define EXT3_JOURNAL_SUPERBLOCK_V1 3 +#define EXT3_JOURNAL_SUPERBLOCK_V2 4 +#define EXT3_JOURNAL_REVOKE_BLOCK 5 + +#define EXT3_JOURNAL_FLAG_ESCAPE 1 +#define EXT3_JOURNAL_FLAG_SAME_UUID 2 +#define EXT3_JOURNAL_FLAG_DELETED 4 +#define EXT3_JOURNAL_FLAG_LAST_TAG 8 + +#define EXT4_EXTENTS_FLAG 0x80000 + +/* The ext2 superblock. */ +struct grub_ext2_sblock +{ + grub_uint32_t total_inodes; + grub_uint32_t total_blocks; + grub_uint32_t reserved_blocks; + grub_uint32_t free_blocks; + grub_uint32_t free_inodes; + grub_uint32_t first_data_block; + grub_uint32_t log2_block_size; + grub_uint32_t log2_fragment_size; + grub_uint32_t blocks_per_group; + grub_uint32_t fragments_per_group; + grub_uint32_t inodes_per_group; + grub_uint32_t mtime; + grub_uint32_t utime; + grub_uint16_t mnt_count; + grub_uint16_t max_mnt_count; + grub_uint16_t magic; + grub_uint16_t fs_state; + grub_uint16_t error_handling; + grub_uint16_t minor_revision_level; + grub_uint32_t lastcheck; + grub_uint32_t checkinterval; + grub_uint32_t creator_os; + grub_uint32_t revision_level; + grub_uint16_t uid_reserved; + grub_uint16_t gid_reserved; + grub_uint32_t first_inode; + grub_uint16_t inode_size; + grub_uint16_t block_group_number; + grub_uint32_t feature_compatibility; + grub_uint32_t feature_incompat; + grub_uint32_t feature_ro_compat; + grub_uint16_t uuid[8]; + char volume_name[16]; + char last_mounted_on[64]; + grub_uint32_t compression_info; + grub_uint8_t prealloc_blocks; + grub_uint8_t prealloc_dir_blocks; + grub_uint16_t reserved_gdt_blocks; + grub_uint8_t journal_uuid[16]; + grub_uint32_t journal_inum; + grub_uint32_t journal_dev; + grub_uint32_t last_orphan; + grub_uint32_t hash_seed[4]; + grub_uint8_t def_hash_version; + grub_uint8_t jnl_backup_type; + grub_uint16_t reserved_word_pad; + grub_uint32_t default_mount_opts; + grub_uint32_t first_meta_bg; + grub_uint32_t mkfs_time; + grub_uint32_t jnl_blocks[17]; +}; + +/* The ext2 blockgroup. */ +struct grub_ext2_block_group +{ + grub_uint32_t block_id; + grub_uint32_t inode_id; + grub_uint32_t inode_table_id; + grub_uint16_t free_blocks; + grub_uint16_t free_inodes; + grub_uint16_t used_dirs; + grub_uint16_t pad; + grub_uint32_t reserved[3]; +}; + +/* The ext2 inode. */ +struct grub_ext2_inode +{ + grub_uint16_t mode; + grub_uint16_t uid; + grub_uint32_t size; + grub_uint32_t atime; + grub_uint32_t ctime; + grub_uint32_t mtime; + grub_uint32_t dtime; + grub_uint16_t gid; + grub_uint16_t nlinks; + grub_uint32_t blockcnt; /* Blocks of 512 bytes!! */ + grub_uint32_t flags; + grub_uint32_t osd1; + union + { + struct datablocks + { + grub_uint32_t dir_blocks[INDIRECT_BLOCKS]; + grub_uint32_t indir_block; + grub_uint32_t double_indir_block; + grub_uint32_t triple_indir_block; + } blocks; + char symlink[60]; + }; + grub_uint32_t version; + grub_uint32_t acl; + grub_uint32_t dir_acl; + grub_uint32_t fragment_addr; + grub_uint32_t osd2[3]; +}; + +/* The header of an ext2 directory entry. */ +struct ext2_dirent +{ + grub_uint32_t inode; + grub_uint16_t direntlen; + grub_uint8_t namelen; + grub_uint8_t filetype; +}; + +struct grub_ext3_journal_header +{ + grub_uint32_t magic; + grub_uint32_t block_type; + grub_uint32_t sequence; +}; + +struct grub_ext3_journal_revoke_header +{ + struct grub_ext3_journal_header header; + grub_uint32_t count; + grub_uint32_t data[0]; +}; + +struct grub_ext3_journal_block_tag +{ + grub_uint32_t block; + grub_uint32_t flags; +}; + +struct grub_ext3_journal_sblock +{ + struct grub_ext3_journal_header header; + grub_uint32_t block_size; + grub_uint32_t maxlen; + grub_uint32_t first; + grub_uint32_t sequence; + grub_uint32_t start; +}; + +#define EXT4_EXT_MAGIC 0xf30a + +struct grub_ext4_extent_header +{ + grub_uint16_t magic; + grub_uint16_t entries; + grub_uint16_t max; + grub_uint16_t depth; + grub_uint32_t generation; +}; + +struct grub_ext4_extent +{ + grub_uint32_t block; + grub_uint16_t len; + grub_uint16_t start_hi; + grub_uint32_t start; +}; + +struct grub_ext4_extent_idx +{ + grub_uint32_t block; + grub_uint32_t leaf; + grub_uint16_t leaf_hi; + grub_uint16_t unused; +}; + +struct grub_fshelp_node +{ + struct grub_ext2_data *data; + struct grub_ext2_inode inode; + int ino; + int inode_read; +}; + +/* Information about a "mounted" ext2 filesystem. */ +struct grub_ext2_data +{ + struct grub_ext2_sblock sblock; + grub_disk_t disk; + struct grub_ext2_inode *inode; + struct grub_fshelp_node diropen; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + + +/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of + the mounted filesystem DATA. */ +inline static grub_err_t +grub_ext2_blockgroup (struct grub_ext2_data *data, int group, + struct grub_ext2_block_group *blkgrp) +{ + return grub_disk_read (data->disk, + ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1) + << LOG2_EXT2_BLOCK_SIZE (data)), + group * sizeof (struct grub_ext2_block_group), + sizeof (struct grub_ext2_block_group), (char *) blkgrp); +} + +static struct grub_ext4_extent_header * +grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf, + struct grub_ext4_extent_header *ext_block, + grub_uint32_t fileblock) +{ + struct grub_ext4_extent_idx *index; + + while (1) + { + int i; + grub_disk_addr_t block; + + index = (struct grub_ext4_extent_idx *) (ext_block + 1); + + if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC) + return 0; + + if (ext_block->depth == 0) + return ext_block; + + for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++) + { + if (fileblock < grub_le_to_cpu32(index[i].block)) + break; + } + + if (--i < 0) + return 0; + + block = grub_le_to_cpu16 (index[i].leaf_hi); + block = (block << 32) + grub_le_to_cpu32 (index[i].leaf); + if (grub_disk_read (data->disk, + block << LOG2_EXT2_BLOCK_SIZE (data), + 0, EXT2_BLOCK_SIZE(data), buf)) + return 0; + + ext_block = (struct grub_ext4_extent_header *) buf; + } +} + +static grub_disk_addr_t +grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_ext2_data *data = node->data; + struct grub_ext2_inode *inode = &node->inode; + int blknr = -1; + unsigned int blksz = EXT2_BLOCK_SIZE (data); + int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); + + if (inode->flags & EXT4_EXTENTS_FLAG) + { + char buf[EXT2_BLOCK_SIZE(data)]; + struct grub_ext4_extent_header *leaf; + struct grub_ext4_extent *ext; + int i; + + leaf = grub_ext4_find_leaf (data, buf, + (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, + fileblock); + if (! leaf) + { + grub_error (GRUB_ERR_BAD_FS, "invalid extent"); + return -1; + } + + ext = (struct grub_ext4_extent *) (leaf + 1); + for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++) + { + if (fileblock < grub_le_to_cpu32 (ext[i].block)) + break; + } + + if (--i >= 0) + { + fileblock -= grub_le_to_cpu32 (ext[i].block); + if (fileblock >= grub_le_to_cpu16 (ext[i].len)) + return 0; + else + { + grub_disk_addr_t start; + + start = grub_le_to_cpu16 (ext[i].start_hi); + start = (start << 32) + grub_le_to_cpu32 (ext[i].start); + + return fileblock + start; + } + } + else + { + grub_error (GRUB_ERR_BAD_FS, "something wrong with extent"); + return -1; + } + } + /* Direct blocks. */ + if (fileblock < INDIRECT_BLOCKS) + blknr = grub_le_to_cpu32 (inode->blocks.dir_blocks[fileblock]); + /* Indirect. */ + else if (fileblock < INDIRECT_BLOCKS + blksz / 4) + { + grub_uint32_t indir[blksz / 4]; + + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (inode->blocks.indir_block) + << log2_blksz, + 0, blksz, (char *) indir)) + return grub_errno; + + blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]); + } + /* Double indirect. */ + else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)) + { + unsigned int perblock = blksz / 4; + unsigned int rblock = fileblock - (INDIRECT_BLOCKS + + blksz / 4); + grub_uint32_t indir[blksz / 4]; + + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (inode->blocks.double_indir_block) + << log2_blksz, + 0, blksz, (char *) indir)) + return grub_errno; + + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (indir[rblock / perblock]) + << log2_blksz, + 0, blksz, (char *) indir)) + return grub_errno; + + + blknr = grub_le_to_cpu32 (indir[rblock % perblock]); + } + /* triple indirect. */ + else + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ext2fs doesn't support triple indirect blocks"); + } + + return blknr; +} + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_ext2_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_ext2_read_block, + node->inode.size, + LOG2_EXT2_BLOCK_SIZE (node->data)); + +} + + +/* Read the inode INO for the file described by DATA into INODE. */ +static grub_err_t +grub_ext2_read_inode (struct grub_ext2_data *data, + int ino, struct grub_ext2_inode *inode) +{ + struct grub_ext2_block_group blkgrp; + struct grub_ext2_sblock *sblock = &data->sblock; + int inodes_per_block; + unsigned int blkno; + unsigned int blkoff; + + /* It is easier to calculate if the first inode is 0. */ + ino--; + + grub_ext2_blockgroup (data, + ino / grub_le_to_cpu32 (sblock->inodes_per_group), + &blkgrp); + if (grub_errno) + return grub_errno; + + inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data); + blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + / inodes_per_block; + blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + % inodes_per_block; + + /* Read the inode. */ + if (grub_disk_read (data->disk, + ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) + << LOG2_EXT2_BLOCK_SIZE (data)), + EXT2_INODE_SIZE (data) * blkoff, + sizeof (struct grub_ext2_inode), (char *) inode)) + return grub_errno; + + return 0; +} + +static struct grub_ext2_data * +grub_ext2_mount (grub_disk_t disk) +{ + struct grub_ext2_data *data; + + data = grub_malloc (sizeof (struct grub_ext2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock), + (char *) &data->sblock); + if (grub_errno) + goto fail; + + /* Make sure this is an ext2 filesystem. */ + if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC) + { + grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem"); + goto fail; + } + + /* Check the FS doesn't have feature bits enabled that we don't support. */ + if (grub_le_to_cpu32 (data->sblock.feature_incompat) + & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT)) + { + grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features"); + goto fail; + } + + + data->disk = disk; + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + + data->inode = &data->diropen.inode; + + grub_ext2_read_inode (data, 2, data->inode); + if (grub_errno) + goto fail; + + return data; + + fail: + grub_free (data); + return 0; +} + +static char * +grub_ext2_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + + if (! diro->inode_read) + { + grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); + if (! symlink) + return 0; + + /* If the filesize of the symlink is bigger than + 60 the symlink is stored in a separate block, + otherwise it is stored in the inode. */ + if (grub_le_to_cpu32 (diro->inode.size) <= 60) + grub_strncpy (symlink, + diro->inode.symlink, + grub_le_to_cpu32 (diro->inode.size)); + else + { + grub_ext2_read_file (diro, 0, 0, + grub_le_to_cpu32 (diro->inode.size), + symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + } + + symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0'; + return symlink; +} + +static int +grub_ext2_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + + if (! diro->inode_read) + { + grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + /* Search the file. */ + while (fpos < grub_le_to_cpu32 (diro->inode.size)) + { + struct ext2_dirent dirent; + + grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent), + (char *) &dirent); + if (grub_errno) + return 0; + + if (dirent.namelen != 0) + { + char filename[dirent.namelen + 1]; + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent), + dirent.namelen, filename); + if (grub_errno) + return 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (! fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = grub_le_to_cpu32 (dirent.inode); + + filename[dirent.namelen] = '\0'; + + if (dirent.filetype != FILETYPE_UNKNOWN) + { + fdiro->inode_read = 0; + + if (dirent.filetype == FILETYPE_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if (dirent.filetype == FILETYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (dirent.filetype == FILETYPE_REG) + type = GRUB_FSHELP_REG; + } + else + { + /* The filetype can not be read from the dirent, read + the inode to get more information. */ + grub_ext2_read_inode (diro->data, + grub_le_to_cpu32 (dirent.inode), + &fdiro->inode); + if (grub_errno) + { + grub_free (fdiro); + return 0; + } + + fdiro->inode_read = 1; + + if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if ((grub_le_to_cpu16 (fdiro->inode.mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + type = GRUB_FSHELP_REG; + } + + if (hook (filename, type, fdiro)) + return 1; + } + + fpos += grub_le_to_cpu16 (dirent.direntlen); + } + + return 0; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_ext2_open (struct grub_file *file, const char *name) +{ + struct grub_ext2_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ext2_mount (file->device->disk); + if (! data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir, + grub_ext2_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (! fdiro->inode_read) + { + grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode)); + grub_free (fdiro); + + file->size = grub_le_to_cpu32 (data->inode->size); + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_ext2_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_ext2_data *data = (struct grub_ext2_data *) file->data; + + return grub_ext2_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + + +static grub_err_t +grub_ext2_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_ext2_data *data = 0;; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ext2_mount (device->disk); + if (! data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir, + grub_ext2_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_ext2_iterate_dir (fdiro, iterate); + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_ext2_label (grub_device_t device, char **label) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ext2_mount (disk); + if (data) + *label = grub_strndup (data->sblock.volume_name, 14); + else + *label = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_ext2_uuid (grub_device_t device, char **uuid) +{ + struct grub_ext2_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ext2_mount (disk); + if (data) + { + *uuid = grub_malloc (40 + sizeof ('\0')); + grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + + +static struct grub_fs grub_ext2_fs = + { + .name = "ext2", + .dir = grub_ext2_dir, + .open = grub_ext2_open, + .read = grub_ext2_read, + .close = grub_ext2_close, + .label = grub_ext2_label, + .uuid = grub_ext2_uuid, + .next = 0 + }; + +GRUB_MOD_INIT(ext2) +{ + grub_fs_register (&grub_ext2_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(ext2) +{ + grub_fs_unregister (&grub_ext2_fs); +} diff --git a/fs/fat.c b/fs/fat.c new file mode 100644 index 0000000..acaa027 --- /dev/null +++ b/fs/fat.c @@ -0,0 +1,888 @@ +/* fat.c - FAT filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_FAT_DIR_ENTRY_SIZE 32 + +#define GRUB_FAT_ATTR_READ_ONLY 0x01 +#define GRUB_FAT_ATTR_HIDDEN 0x02 +#define GRUB_FAT_ATTR_SYSTEM 0x04 +#define GRUB_FAT_ATTR_VOLUME_ID 0x08 +#define GRUB_FAT_ATTR_DIRECTORY 0x10 +#define GRUB_FAT_ATTR_ARCHIVE 0x20 + +#define GRUB_FAT_MAXFILE 256 + +#define GRUB_FAT_ATTR_LONG_NAME (GRUB_FAT_ATTR_READ_ONLY \ + | GRUB_FAT_ATTR_HIDDEN \ + | GRUB_FAT_ATTR_SYSTEM \ + | GRUB_FAT_ATTR_VOLUME_ID) +#define GRUB_FAT_ATTR_VALID (GRUB_FAT_ATTR_READ_ONLY \ + | GRUB_FAT_ATTR_HIDDEN \ + | GRUB_FAT_ATTR_SYSTEM \ + | GRUB_FAT_ATTR_DIRECTORY \ + | GRUB_FAT_ATTR_ARCHIVE) + +struct grub_fat_bpb +{ + grub_uint8_t jmp_boot[3]; + grub_uint8_t oem_name[8]; + grub_uint16_t bytes_per_sector; + grub_uint8_t sectors_per_cluster; + grub_uint16_t num_reserved_sectors; + grub_uint8_t num_fats; + grub_uint16_t num_root_entries; + grub_uint16_t num_total_sectors_16; + grub_uint8_t media; + grub_uint16_t sectors_per_fat_16; + grub_uint16_t sectors_per_track; + grub_uint16_t num_heads; + grub_uint32_t num_hidden_sectors; + grub_uint32_t num_total_sectors_32; + union + { + struct + { + grub_uint8_t num_ph_drive; + grub_uint8_t reserved; + grub_uint8_t boot_sig; + grub_uint32_t num_serial; + grub_uint8_t label[11]; + grub_uint8_t fstype[8]; + } __attribute__ ((packed)) fat12_or_fat16; + struct + { + grub_uint32_t sectors_per_fat_32; + grub_uint16_t extended_flags; + grub_uint16_t fs_version; + grub_uint32_t root_cluster; + grub_uint16_t fs_info; + grub_uint16_t backup_boot_sector; + grub_uint8_t reserved[12]; + grub_uint8_t num_ph_drive; + grub_uint8_t reserved1; + grub_uint8_t boot_sig; + grub_uint32_t num_serial; + grub_uint8_t label[11]; + grub_uint8_t fstype[8]; + } __attribute__ ((packed)) fat32; + } __attribute__ ((packed)) version_specific; +} __attribute__ ((packed)); + +struct grub_fat_dir_entry +{ + grub_uint8_t name[11]; + grub_uint8_t attr; + grub_uint8_t nt_reserved; + grub_uint8_t c_time_tenth; + grub_uint16_t c_time; + grub_uint16_t c_date; + grub_uint16_t a_date; + grub_uint16_t first_cluster_high; + grub_uint16_t w_time; + grub_uint16_t w_date; + grub_uint16_t first_cluster_low; + grub_uint32_t file_size; +} __attribute__ ((packed)); + +struct grub_fat_long_name_entry +{ + grub_uint8_t id; + grub_uint16_t name1[5]; + grub_uint8_t attr; + grub_uint8_t reserved; + grub_uint8_t checksum; + grub_uint16_t name2[6]; + grub_uint16_t first_cluster; + grub_uint16_t name3[2]; +} __attribute__ ((packed)); + +struct grub_fat_data +{ + int logical_sector_bits; + grub_uint32_t num_sectors; + + grub_uint16_t fat_sector; + grub_uint32_t sectors_per_fat; + int fat_size; + + grub_uint32_t root_cluster; + grub_uint32_t root_sector; + grub_uint32_t num_root_sectors; + + int cluster_bits; + grub_uint32_t cluster_eof_mark; + grub_uint32_t cluster_sector; + grub_uint32_t num_clusters; + + grub_uint8_t attr; + grub_ssize_t file_size; + grub_uint32_t file_cluster; + grub_uint32_t cur_cluster_num; + grub_uint32_t cur_cluster; + + grub_uint32_t uuid; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static int +fat_log2 (unsigned x) +{ + int i; + + if (x == 0) + return -1; + + for (i = 0; (x & 1) == 0; i++) + x >>= 1; + + if (x != 1) + return -1; + + return i; +} + +static struct grub_fat_data * +grub_fat_mount (grub_disk_t disk) +{ + struct grub_fat_bpb bpb; + struct grub_fat_data *data = 0; + grub_uint32_t first_fat, magic; + + if (! disk) + goto fail; + + data = (struct grub_fat_data *) grub_malloc (sizeof (*data)); + if (! data) + goto fail; + + /* Read the BPB. */ + if (grub_disk_read (disk, 0, 0, sizeof (bpb), (char *) &bpb)) + goto fail; + + if (grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT12", 5) + && grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5) + && grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5)) + goto fail; + + /* Get the sizes of logical sectors and clusters. */ + data->logical_sector_bits = + fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector)); + if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS) + goto fail; + data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS; + + data->cluster_bits = fat_log2 (bpb.sectors_per_cluster); + if (data->cluster_bits < 0) + goto fail; + data->cluster_bits += data->logical_sector_bits; + + /* Get information about FATs. */ + data->fat_sector = (grub_le_to_cpu16 (bpb.num_reserved_sectors) + << data->logical_sector_bits); + if (data->fat_sector == 0) + goto fail; + + data->sectors_per_fat = ((bpb.sectors_per_fat_16 + ? grub_le_to_cpu16 (bpb.sectors_per_fat_16) + : grub_le_to_cpu32 (bpb.version_specific.fat32.sectors_per_fat_32)) + << data->logical_sector_bits); + if (data->sectors_per_fat == 0) + goto fail; + + /* Get the number of sectors in this volume. */ + data->num_sectors = ((bpb.num_total_sectors_16 + ? grub_le_to_cpu16 (bpb.num_total_sectors_16) + : grub_le_to_cpu32 (bpb.num_total_sectors_32)) + << data->logical_sector_bits); + if (data->num_sectors == 0) + goto fail; + + /* Get information about the root directory. */ + if (bpb.num_fats == 0) + goto fail; + + data->root_sector = data->fat_sector + bpb.num_fats * data->sectors_per_fat; + data->num_root_sectors + = ((((grub_uint32_t) grub_le_to_cpu16 (bpb.num_root_entries) + * GRUB_FAT_DIR_ENTRY_SIZE + + grub_le_to_cpu16 (bpb.bytes_per_sector) - 1) + >> (data->logical_sector_bits + GRUB_DISK_SECTOR_BITS)) + << (data->logical_sector_bits)); + + data->cluster_sector = data->root_sector + data->num_root_sectors; + data->num_clusters = (((data->num_sectors - data->cluster_sector) + >> (data->cluster_bits + data->logical_sector_bits)) + + 2); + + if (data->num_clusters <= 2) + goto fail; + + if (! bpb.sectors_per_fat_16) + { + /* FAT32. */ + grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags); + + data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster); + data->fat_size = 32; + data->cluster_eof_mark = 0x0ffffff8; + + if (flags & 0x80) + { + /* Get an active FAT. */ + unsigned active_fat = flags & 0xf; + + if (active_fat > bpb.num_fats) + goto fail; + + data->fat_sector += active_fat * data->sectors_per_fat; + } + + if (bpb.num_root_entries != 0 || bpb.version_specific.fat32.fs_version != 0) + goto fail; + } + else + { + /* FAT12 or FAT16. */ + data->root_cluster = ~0U; + + if (data->num_clusters <= 4085 + 2) + { + /* FAT12. */ + data->fat_size = 12; + data->cluster_eof_mark = 0x0ff8; + } + else + { + /* FAT16. */ + data->fat_size = 16; + data->cluster_eof_mark = 0xfff8; + } + } + + /* More sanity checks. */ + if (data->num_sectors <= data->fat_sector) + goto fail; + + if (grub_disk_read (disk, + data->fat_sector, + 0, + sizeof (first_fat), + (char *) &first_fat)) + goto fail; + + first_fat = grub_le_to_cpu32 (first_fat); + + if (data->fat_size == 32) + { + first_fat &= 0x0fffffff; + magic = 0x0fffff00; + } + else if (data->fat_size == 16) + { + first_fat &= 0x0000ffff; + magic = 0xff00; + } + else + { + first_fat &= 0x00000fff; + magic = 0x0f00; + } + + /* Serial number. */ + if (bpb.sectors_per_fat_16) + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial); + else + data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial); + + /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media + descriptor, even if it is a so-called superfloppy (e.g. an USB key). + The check may be too strict for this kind of stupid BIOSes, as + they overwrite the media descriptor. */ + if ((first_fat | 0x8) != (magic | bpb.media | 0x8)) + goto fail; + + /* Start from the root directory. */ + data->file_cluster = data->root_cluster; + data->cur_cluster_num = ~0U; + data->attr = GRUB_FAT_ATTR_DIRECTORY; + return data; + + fail: + + grub_free (data); + grub_error (GRUB_ERR_BAD_FS, "not a fat filesystem"); + return 0; +} + +static grub_ssize_t +grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + grub_off_t offset, grub_size_t len, char *buf) +{ + grub_size_t size; + grub_uint32_t logical_cluster; + unsigned logical_cluster_bits; + grub_ssize_t ret = 0; + unsigned long sector; + + /* This is a special case. FAT12 and FAT16 doesn't have the root directory + in clusters. */ + if (data->file_cluster == ~0U) + { + size = (data->num_root_sectors << GRUB_DISK_SECTOR_BITS) - offset; + if (size > len) + size = len; + + if (grub_disk_read (disk, data->root_sector, offset, size, buf)) + return -1; + + return size; + } + + /* Calculate the logical cluster number and offset. */ + logical_cluster_bits = (data->cluster_bits + + data->logical_sector_bits + + GRUB_DISK_SECTOR_BITS); + logical_cluster = offset >> logical_cluster_bits; + offset &= (1 << logical_cluster_bits) - 1; + + if (logical_cluster < data->cur_cluster_num) + { + data->cur_cluster_num = 0; + data->cur_cluster = data->file_cluster; + } + + while (len) + { + while (logical_cluster > data->cur_cluster_num) + { + /* Find next cluster. */ + grub_uint32_t next_cluster; + unsigned long fat_offset; + + switch (data->fat_size) + { + case 32: + fat_offset = data->cur_cluster << 2; + break; + case 16: + fat_offset = data->cur_cluster << 1; + break; + default: + /* case 12: */ + fat_offset = data->cur_cluster + (data->cur_cluster >> 1); + break; + } + + /* Read the FAT. */ + if (grub_disk_read (disk, data->fat_sector, fat_offset, + (data->fat_size + 7) >> 3, + (char *) &next_cluster)) + return -1; + + next_cluster = grub_le_to_cpu32 (next_cluster); + switch (data->fat_size) + { + case 16: + next_cluster &= 0xFFFF; + break; + case 12: + if (data->cur_cluster & 1) + next_cluster >>= 4; + + next_cluster &= 0x0FFF; + break; + } + +#if 0 + grub_printf ("%s:%d: fat_size=%d, next_cluster=%u\n", + __FILE__, __LINE__, data->fat_size, next_cluster); +#endif + + /* Check the end. */ + if (next_cluster >= data->cluster_eof_mark) + return ret; + + if (next_cluster < 2 || next_cluster >= data->num_clusters) + { + grub_error (GRUB_ERR_BAD_FS, "invalid cluster %u", + next_cluster); + return -1; + } + + data->cur_cluster = next_cluster; + data->cur_cluster_num++; + } + + /* Read the data here. */ + sector = (data->cluster_sector + + ((data->cur_cluster - 2) + << (data->cluster_bits + data->logical_sector_bits))); + size = (1 << logical_cluster_bits) - offset; + if (size > len) + size = len; + + disk->read_hook = read_hook; + grub_disk_read (disk, sector, offset, size, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + + len -= size; + buf += size; + ret += size; + logical_cluster++; + offset = 0; + } + + return ret; +} + +/* Find the underlying directory or file in PATH and return the + next path. If there is no next path or an error occurs, return NULL. + If HOOK is specified, call it with each file name. */ +static char * +grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, + const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_fat_dir_entry dir; + char *dirname, *dirp; + char *filename, *filep = 0; + grub_uint16_t *unibuf; + int slot = -1, slots = -1; + int checksum = -1; + grub_ssize_t offset = -sizeof(dir); + int call_hook; + + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return 0; + } + + /* Extract a directory name. */ + while (*path == '/') + path++; + + dirp = grub_strchr (path, '/'); + if (dirp) + { + unsigned len = dirp - path; + + dirname = grub_malloc (len + 1); + if (! dirname) + return 0; + + grub_memcpy (dirname, path, len); + dirname[len] = '\0'; + } + else + /* This is actually a file. */ + dirname = grub_strdup (path); + + call_hook = (! dirp && hook); + + /* Allocate space enough to hold a long name. */ + filename = grub_malloc (0x40 * 13 * 4 + 1); + unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2); + if (! filename || ! unibuf) + { + grub_free (filename); + grub_free (unibuf); + grub_free (dirname); + return 0; + } + + while (1) + { + unsigned i; + + /* Adjust the offset. */ + offset += sizeof (dir); + + /* Read a directory entry. */ + if ((grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + || dir.name[0] == 0) + { + if (grub_errno == GRUB_ERR_NONE && ! call_hook) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + + break; + } + + /* Handle long name entries. */ + if (dir.attr == GRUB_FAT_ATTR_LONG_NAME) + { + struct grub_fat_long_name_entry *long_name + = (struct grub_fat_long_name_entry *) &dir; + grub_uint8_t id = long_name->id; + + if (id & 0x40) + { + id &= 0x3f; + slots = slot = id; + checksum = long_name->checksum; + } + + if (id != slot || slot == 0 || checksum != long_name->checksum) + { + checksum = -1; + continue; + } + + slot--; + grub_memcpy (unibuf + slot * 13, long_name->name1, 5 * 2); + grub_memcpy (unibuf + slot * 13 + 5, long_name->name2, 6 * 2); + grub_memcpy (unibuf + slot * 13 + 11, long_name->name3, 2 * 2); + continue; + } + + /* Check if this entry is valid. */ + if (dir.name[0] == 0xe5 || (dir.attr & ~GRUB_FAT_ATTR_VALID)) + continue; + + /* This is a workaround for Japanese. */ + if (dir.name[0] == 0x05) + dir.name[0] = 0xe5; + + if (checksum != -1 && slot == 0) + { + grub_uint8_t sum; + + for (sum = 0, i = 0; i < sizeof (dir.name); i++) + sum = ((sum >> 1) | (sum << 7)) + dir.name[i]; + + if (sum == checksum) + { + int u; + + for (u = 0; u < slots * 13; u++) + unibuf[u] = grub_le_to_cpu16 (unibuf[u]); + + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf, + slots * 13) = '\0'; + + if (*dirname == '\0' && call_hook) + { + if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY)) + break; + + checksum = -1; + continue; + } + + if (grub_strcmp (dirname, filename) == 0) + { + if (call_hook) + hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY); + + break; + } + } + + checksum = -1; + } + + /* Convert the 8.3 file name. */ + filep = filename; + + for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++) + *filep++ = grub_tolower (dir.name[i]); + + *filep = '.'; + + for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++) + *++filep = grub_tolower (dir.name[i]); + + if (*filep != '.') + filep++; + + *filep = '\0'; + + if (*dirname == '\0' && call_hook) + { + if (hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY)) + break; + } + else if (grub_strncasecmp (dirname, filename, GRUB_FAT_MAXFILE) == 0) + { + if (call_hook) + hook (filename, dir.attr & GRUB_FAT_ATTR_DIRECTORY); + + break; + } + } + + grub_free (filename); + grub_free (dirname); + + data->attr = dir.attr; + data->file_size = grub_le_to_cpu32 (dir.file_size); + data->file_cluster = ((grub_le_to_cpu16 (dir.first_cluster_high) << 16) + | grub_le_to_cpu16 (dir.first_cluster_low)); + data->cur_cluster_num = ~0U; + + return dirp; +} + +static grub_err_t +grub_fat_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_fat_data *data = 0; + grub_disk_t disk = device->disk; + grub_size_t len; + char *dirname = 0; + char *p; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_fat_mount (disk); + if (! data) + goto fail; + + /* Make sure that DIRNAME terminates with '/'. */ + len = grub_strlen (path); + dirname = grub_malloc (len + 1 + 1); + if (! dirname) + goto fail; + grub_memcpy (dirname, path, len); + p = dirname + len; + if (path[len - 1] != '/') + *p++ = '/'; + *p = '\0'; + p = dirname; + + do + { + p = grub_fat_find_dir (disk, data, p, hook); + } + while (p && grub_errno == GRUB_ERR_NONE); + + fail: + + grub_free (dirname); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_fat_open (grub_file_t file, const char *name) +{ + struct grub_fat_data *data = 0; + char *p = (char *) name; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_fat_mount (file->device->disk); + if (! data) + goto fail; + + do + { + p = grub_fat_find_dir (file->device->disk, data, p, 0); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + } + while (p); + + if (data->attr & GRUB_FAT_ATTR_DIRECTORY) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file"); + goto fail; + } + + file->data = data; + file->size = data->file_size; + + return GRUB_ERR_NONE; + + fail: + + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_ssize_t +grub_fat_read (grub_file_t file, char *buf, grub_size_t len) +{ + return grub_fat_read_data (file->device->disk, file->data, file->read_hook, + file->offset, len, buf); +} + +static grub_err_t +grub_fat_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_fat_label (grub_device_t device, char **label) +{ + struct grub_fat_data *data; + grub_disk_t disk = device->disk; + grub_ssize_t offset = -sizeof(struct grub_fat_dir_entry); + + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_fat_mount (disk); + if (! data) + goto fail; + + if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return 0; + } + + while (1) + { + struct grub_fat_dir_entry dir; + + /* Adjust the offset. */ + offset += sizeof (dir); + + /* Read a directory entry. */ + if ((grub_fat_read_data (disk, data, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + || dir.name[0] == 0) + { + if (grub_errno != GRUB_ERR_NONE) + goto fail; + else + { + *label = 0; + return GRUB_ERR_NONE; + } + } + + if (dir.attr == GRUB_FAT_ATTR_VOLUME_ID) + { + *label = grub_strndup ((char *) dir.name, 11); + return GRUB_ERR_NONE; + } + } + + *label = 0; + + fail: + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_fat_uuid (grub_device_t device, char **uuid) +{ + struct grub_fat_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_fat_mount (disk); + if (data) + { + *uuid = grub_malloc (sizeof ("xxxx-xxxx")); + grub_sprintf (*uuid, "%04x-%04x", (grub_uint16_t) (data->uuid >> 16), + (grub_uint16_t) data->uuid); + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static struct grub_fs grub_fat_fs = + { + .name = "fat", + .dir = grub_fat_dir, + .open = grub_fat_open, + .read = grub_fat_read, + .close = grub_fat_close, + .label = grub_fat_label, + .uuid = grub_fat_uuid, + .next = 0 + }; + +GRUB_MOD_INIT(fat) +{ + grub_fs_register (&grub_fat_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(fat) +{ + grub_fs_unregister (&grub_fat_fs); +} + diff --git a/fs/fshelp.c b/fs/fshelp.c new file mode 100644 index 0000000..a5eccdd --- /dev/null +++ b/fs/fshelp.c @@ -0,0 +1,315 @@ +/* fshelp.c -- Filesystem helper functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + + +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. Make + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required + because GCC has a nasty bug when using regparm=3. */ +grub_err_t +grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + int (*iterate_dir) (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR (*hook) + (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)), + char *(*read_symlink) (grub_fshelp_node_t node), + enum grub_fshelp_filetype expecttype) +{ + grub_err_t err; + enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR; + int symlinknest = 0; + + auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, + grub_fshelp_node_t currroot, + grub_fshelp_node_t *currfound); + + grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, + grub_fshelp_node_t currroot, + grub_fshelp_node_t *currfound) + { + char fpath[grub_strlen (currpath) + 1]; + char *name = fpath; + char *next; + // unsigned int pos = 0; + enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; + grub_fshelp_node_t currnode = currroot; + grub_fshelp_node_t oldnode = currroot; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + auto void free_node (grub_fshelp_node_t node); + + void free_node (grub_fshelp_node_t node) + { + if (node != rootnode && node != currroot) + grub_free (node); + } + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + if (filetype == GRUB_FSHELP_UNKNOWN || + (grub_strcmp (name, filename) && + (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) || + grub_strncasecmp (name, filename, LONG_MAX)))) + { + grub_free (node); + return 0; + } + + /* The node is found, stop iterating over the nodes. */ + type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; + oldnode = currnode; + currnode = node; + + return 1; + } + + grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1); + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + if (! *name) + { + *currfound = currnode; + return 0; + } + + for (;;) + { + int found; + + /* Extract the actual part from the pathname. */ + next = grub_strchr (name, '/'); + if (next) + { + /* Remove all leading slashes. */ + while (*next == '/') + *(next++) = '\0'; + } + + /* At this point it is expected that the current node is a + directory, check if this is true. */ + if (type != GRUB_FSHELP_DIR) + { + free_node (currnode); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + } + + /* Iterate over the directory. */ + found = iterate_dir (currnode, iterate); + if (! found) + { + if (grub_errno) + return grub_errno; + + break; + } + + /* Read in the symlink and follow it. */ + if (type == GRUB_FSHELP_SYMLINK) + { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++symlinknest == 8) + { + free_node (currnode); + free_node (oldnode); + return grub_error (GRUB_ERR_SYMLINK_LOOP, + "too deep nesting of symlinks"); + } + + symlink = read_symlink (currnode); + free_node (currnode); + + if (!symlink) + { + free_node (oldnode); + return grub_errno; + } + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + { + free_node (oldnode); + oldnode = rootnode; + } + + /* Lookup the node the symlink points to. */ + find_file (symlink, oldnode, &currnode); + type = foundtype; + grub_free (symlink); + + if (grub_errno) + { + free_node (oldnode); + return grub_errno; + } + } + + free_node (oldnode); + + /* Found the node! */ + if (! next || *next == '\0') + { + *currfound = currnode; + foundtype = type; + return 0; + } + + name = next; + } + + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + } + + if (!path || path[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return grub_errno; + } + + err = find_file (path, rootnode, foundnode); + if (err) + return err; + + /* Check if the node that was found was of the expected type. */ + if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + return 0; +} + +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, + beginning with the block POS. READ_HOOK should be set before + reading a block from the file. GET_BLOCK is used to translate file + blocks to disk blocks. The file is FILESIZE bytes big and the + blocks have a size of LOG2BLOCKSIZE (in log2). */ +grub_ssize_t +grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length), + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), + grub_off_t filesize, int log2blocksize) +{ + grub_disk_addr_t i, blockcnt; + int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS); + + /* Adjust LEN so it we can't read past the end of the file. */ + if (pos + len > filesize) + len = filesize - pos; + + blockcnt = ((len + pos) + blocksize - 1) >> (log2blocksize + GRUB_DISK_SECTOR_BITS); + + for (i = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); i < blockcnt; i++) + { + grub_disk_addr_t blknr; + int blockoff = pos & (blocksize - 1); + int blockend = blocksize; + + int skipfirst = 0; + + blknr = get_block (node, i); + if (grub_errno) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) & (blocksize - 1); + + /* The last portion is exactly blocksize. */ + if (! blockend) + blockend = blocksize; + } + + /* First block. */ + if (i == (pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS))) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) + { + disk->read_hook = read_hook; + + grub_disk_read (disk, blknr, skipfirst, + blockend, buf); + disk->read_hook = 0; + if (grub_errno) + return -1; + } + else + grub_memset (buf, 0, blockend); + + buf += blocksize - skipfirst; + } + + return len; +} + +unsigned int +grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) +{ + int mod; + + *pow = 0; + while (blksize > 1) + { + mod = blksize - ((blksize >> 1) << 1); + blksize >>= 1; + + /* Check if it really is a power of two. */ + if (mod) + return grub_error (GRUB_ERR_BAD_NUMBER, + "the blocksize is not a power of two"); + (*pow)++; + } + + return GRUB_ERR_NONE; +} diff --git a/fs/hfs.c b/fs/hfs.c new file mode 100644 index 0000000..b01c42e --- /dev/null +++ b/fs/hfs.c @@ -0,0 +1,886 @@ +/* hfs.c - HFS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* HFS is documented at + http://developer.apple.com/documentation/mac/Files/Files-2.html */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_HFS_SBLOCK 2 +#define GRUB_HFS_EMBED_HFSPLUS_SIG 0x482B + +#define GRUB_HFS_BLKS (data->blksz >> 9) + +#define GRUB_HFS_NODE_LEAF 0xFF + +/* The two supported filesystems a record can have. */ +enum + { + GRUB_HFS_FILETYPE_DIR = 1, + GRUB_HFS_FILETYPE_FILE = 2 + }; + +/* Catalog node ID (CNID). */ +enum grub_hfs_cnid_type + { + GRUB_HFS_CNID_ROOT_PARENT = 1, + GRUB_HFS_CNID_ROOT = 2, + GRUB_HFS_CNID_EXT = 3, + GRUB_HFS_CNID_CAT = 4, + GRUB_HFS_CNID_BAD = 5 + }; + +/* A node descriptor. This is the header of every node. */ +struct grub_hfs_node +{ + grub_uint32_t next; + grub_uint32_t prev; + grub_uint8_t type; + grub_uint8_t level; + grub_uint16_t reccnt; + grub_uint16_t unused; +} __attribute__ ((packed)); + +/* The head of the B*-Tree. */ +struct grub_hfs_treeheader +{ + grub_uint16_t tree_depth; + /* The number of the first node. */ + grub_uint32_t root_node; + grub_uint32_t leaves; + grub_uint32_t first_leaf; + grub_uint32_t last_leaf; + grub_uint16_t node_size; + grub_uint16_t key_size; + grub_uint32_t nodes; + grub_uint32_t free_nodes; + grub_uint8_t unused[76]; +} __attribute__ ((packed)); + +/* The state of a mounted HFS filesystem. */ +struct grub_hfs_data +{ + struct grub_hfs_sblock sblock; + grub_disk_t disk; + grub_hfs_datarecord_t extents; + int fileid; + int size; + int ext_root; + int ext_size; + int cat_root; + int cat_size; + int blksz; + int log2_blksz; + int rootdir; +}; + +/* The key as used on disk in a catalog tree. This is used to lookup + file/directory nodes by parent directory ID and filename. */ +struct grub_hfs_catalog_key +{ + grub_uint8_t unused; + grub_uint32_t parent_dir; + + /* Filename length. */ + grub_uint8_t strlen; + + /* Filename. */ + grub_uint8_t str[31]; +} __attribute__ ((packed)); + +/* The key as used on disk in a extent overflow tree. Using this key + the extents can be looked up using a fileid and logical start block + as index. */ +struct grub_hfs_extent_key +{ + /* The kind of fork. This is used to store meta information like + icons, attributes, etc. We will only use the datafork, which is + 0. */ + grub_uint8_t forktype; + grub_uint32_t fileid; + grub_uint16_t first_block; +} __attribute__ ((packed)); + +/* A dirrect record. This is used to find out the directory ID. */ +struct grub_hfs_dirrec +{ + /* For a directory, type == 1. */ + grub_uint8_t type; + grub_uint8_t unused[5]; + grub_uint32_t dirid; +} __attribute__ ((packed)); + +/* Information about a file. */ +struct grub_hfs_filerec +{ + /* For a file, type == 2. */ + grub_uint8_t type; + grub_uint8_t unused[19]; + grub_uint32_t fileid; + grub_uint8_t unused2[2]; + grub_uint32_t size; + grub_uint8_t unused3[44]; + + /* The first 3 extents of the file. The other extents can be found + in the extent overflow file. */ + grub_hfs_datarecord_t extents; +} __attribute__ ((packed)); + +/* A record descriptor, both key and data, used to pass to call back + functions. */ +struct grub_hfs_record +{ + void *key; + int keylen; + void *data; + int datalen; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static int grub_hfs_find_node (struct grub_hfs_data *, char *, + grub_uint32_t, int, char *, int); + +/* Find block BLOCK of the file FILE in the mounted UFS filesystem + DATA. The first 3 extents are described by DAT. If cache is set, + using caching to improve non-random reads. */ +static unsigned int +grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat, + int file, int block, int cache) +{ + grub_hfs_datarecord_t dr; + int pos = 0; + struct grub_hfs_extent_key key; + + int tree = 0; + static int cache_file = 0; + static int cache_pos = 0; + static grub_hfs_datarecord_t cache_dr; + + grub_memcpy (dr, dat, sizeof (dr)); + + key.forktype = 0; + key.fileid = grub_cpu_to_be32 (file); + + if (cache && cache_file == file && block > cache_pos) + { + pos = cache_pos; + key.first_block = grub_cpu_to_be16 (pos); + grub_memcpy (dr, cache_dr, sizeof (cache_dr)); + } + + for (;;) + { + int i; + + /* Try all 3 extents. */ + for (i = 0; i < 3; i++) + { + /* Check if the block is stored in this extent. */ + if (grub_be_to_cpu16 (dr[i].count) + pos > block) + { + int first = grub_be_to_cpu16 (dr[i].first_block); + + /* If the cache is enabled, store the current position + in the tree. */ + if (tree && cache) + { + cache_file = file; + cache_pos = pos; + grub_memcpy (cache_dr, dr, sizeof (cache_dr)); + } + + return (grub_be_to_cpu16 (data->sblock.first_block) + + (first + block - pos) * GRUB_HFS_BLKS); + } + + /* Try the next extent. */ + pos += grub_be_to_cpu16 (dr[i].count); + } + + /* Lookup the block in the extent overflow file. */ + key.first_block = grub_cpu_to_be16 (pos); + tree = 1; + grub_hfs_find_node (data, (char *) &key, data->ext_root, + 1, (char *) &dr, sizeof (dr)); + if (grub_errno) + return 0; + } +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_hfs_read_file (struct grub_hfs_data *data, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + int i; + int blockcnt; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > grub_le_to_cpu32 (data->size)) + len = grub_le_to_cpu32 (data->size); + + blockcnt = ((len + pos) + + data->blksz - 1) / data->blksz; + + for (i = pos / data->blksz; i < blockcnt; i++) + { + int blknr; + int blockoff = pos % data->blksz; + int blockend = data->blksz; + + int skipfirst = 0; + + blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1); + if (grub_errno) + return -1; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) % data->blksz; + + /* The last portion is exactly EXT2_BLOCK_SIZE (data). */ + if (! blockend) + blockend = data->blksz; + } + + /* First block. */ + if (i == pos / data->blksz) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* If the block number is 0 this block is not stored on disk but + is zero filled instead. */ + if (blknr) + { + data->disk->read_hook = read_hook; + grub_disk_read (data->disk, blknr, skipfirst, + blockend, buf); + data->disk->read_hook = 0; + if (grub_errno) + return -1; + } + + buf += data->blksz - skipfirst; + } + + return len; +} + + +/* Mount the filesystem on the disk DISK. */ +static struct grub_hfs_data * +grub_hfs_mount (grub_disk_t disk) +{ + struct grub_hfs_data *data; + struct grub_hfs_catalog_key key; + struct grub_hfs_dirrec dir; + int first_block; + + struct + { + struct grub_hfs_node node; + struct grub_hfs_treeheader head; + } treehead; + + data = grub_malloc (sizeof (struct grub_hfs_data)); + if (!data) + return 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0, + sizeof (struct grub_hfs_sblock), (char *) &data->sblock)) + goto fail; + + /* Check if this is a HFS filesystem. */ + if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC) + { + grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem"); + goto fail; + } + + /* Check if this is an embedded HFS+ filesystem. */ + if (grub_be_to_cpu16 (data->sblock.embed_sig) == GRUB_HFS_EMBED_HFSPLUS_SIG) + { + grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem"); + goto fail; + } + + data->blksz = grub_be_to_cpu32 (data->sblock.blksz); + data->disk = disk; + + /* Lookup the root node of the extent overflow tree. */ + first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block) + * GRUB_HFS_BLKS) + + grub_be_to_cpu16 (data->sblock.first_block)); + + if (grub_disk_read (data->disk, first_block, 0, + sizeof (treehead), (char *) &treehead)) + goto fail; + data->ext_root = grub_be_to_cpu32 (treehead.head.root_node); + data->ext_size = grub_be_to_cpu16 (treehead.head.node_size); + + /* Lookup the root node of the catalog tree. */ + first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block) + * GRUB_HFS_BLKS) + + grub_be_to_cpu16 (data->sblock.first_block)); + if (grub_disk_read (data->disk, first_block, 0, + sizeof (treehead), (char *) &treehead)) + goto fail; + data->cat_root = grub_be_to_cpu32 (treehead.head.root_node); + data->cat_size = grub_be_to_cpu16 (treehead.head.node_size); + + /* Lookup the root directory node in the catalog tree using the + volume name. */ + key.parent_dir = grub_cpu_to_be32 (1); + key.strlen = data->sblock.volname[0]; + grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1)); + + if (grub_hfs_find_node (data, (char *) &key, data->cat_root, + 0, (char *) &dir, sizeof (dir)) == 0) + { + grub_error (GRUB_ERR_BAD_FS, "can not find the hfs root directory"); + goto fail; + } + + if (grub_errno) + goto fail; + + data->rootdir = grub_be_to_cpu32 (dir.dirid); + + return data; + fail: + grub_free (data); + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a hfs filesystem"); + + return 0; +} + + +/* Compare the K1 and K2 catalog file keys. */ +static int +grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1, + struct grub_hfs_catalog_key *k2) +{ + int cmp = (grub_be_to_cpu32 (k1->parent_dir) + - grub_be_to_cpu32 (k2->parent_dir)); + + if (cmp != 0) + return cmp; + + cmp = grub_strncasecmp ((char *) (k1->str), (char *) (k2->str), k1->strlen); + + /* This is required because the compared strings are not of equal + length. */ + if (cmp == 0 && k1->strlen < k2->strlen) + return -1; + return cmp; +} + + +/* Compare the K1 and K2 extent overflow file keys. */ +static int +grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1, + struct grub_hfs_extent_key *k2) +{ + int cmp = k1->forktype - k2->forktype; + if (cmp == 0) + cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid); + if (cmp == 0) + cmp = (grub_be_to_cpu16 (k1->first_block) + - grub_be_to_cpu16 (k2->first_block)); + return cmp; +} + + +/* Iterate the records in the node with index IDX in the mounted HFS + filesystem DATA. This node holds data of the type TYPE (0 = + catalog node, 1 = extent overflow node). If this is set, continue + iterating to the next node. For every records, call NODE_HOOK. */ +static grub_err_t +grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, + int this, int (*node_hook) (struct grub_hfs_node *hnd, + struct grub_hfs_record *)) +{ + int nodesize = type == 0 ? data->cat_size : data->ext_size; + + union + { + struct grub_hfs_node node; + char rawnode[nodesize]; + grub_uint16_t offsets[nodesize / 2]; + } node; + + do + { + int i; + struct grub_hfs_extent *dat; + int blk; + + dat = (struct grub_hfs_extent *) (type == 0 + ? (&data->sblock.catalog_recs) + : (&data->sblock.extent_recs)); + + /* Read the node into memory. */ + blk = grub_hfs_block (data, dat, + (type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT, + idx / (data->blksz / nodesize), 0); + blk += (idx % (data->blksz / nodesize)); + if (grub_errno) + return grub_errno; + + if (grub_disk_read (data->disk, blk, 0, + sizeof (node), (char *) &node)) + return grub_errno; + + /* Iterate over all records in this node. */ + for (i = 0; i < grub_be_to_cpu16 (node.node.reccnt); i++) + { + int pos = (nodesize >> 1) - 1 - i; + struct pointer + { + grub_uint8_t keylen; + grub_uint8_t key; + } __attribute__ ((packed)) *pnt; + pnt = (struct pointer *) (grub_be_to_cpu16 (node.offsets[pos]) + + node.rawnode); + + struct grub_hfs_record rec = + { + &pnt->key, + pnt->keylen, + &pnt->key + pnt->keylen +(pnt->keylen + 1) % 2, + nodesize - grub_be_to_cpu16 (node.offsets[pos]) + - pnt->keylen - 1 + }; + + if (node_hook (&node.node, &rec)) + return 0; + } + + idx = grub_be_to_cpu32 (node.node.next); + } while (idx && this); + + return 0; +} + + +/* Lookup a record in the mounted filesystem DATA using the key KEY. + The index of the node on top of the tree is IDX. The tree is of + the type TYPE (0 = catalog node, 1 = extent overflow node). Return + the data in DATAR with a maximum length of DATALEN. */ +static int +grub_hfs_find_node (struct grub_hfs_data *data, char *key, + grub_uint32_t idx, int type, char *datar, int datalen) +{ + int found = -1; + int isleaf = 0; + int done = 0; + + auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); + + int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) + { + int cmp = 1; + + if (type == 0) + cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key); + else + cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key); + + /* If the key is smaller or equal to the currect node, mark the + entry. In case of a non-leaf mode it will be used to lookup + the rest of the tree. */ + if (cmp <= 0) + { + grub_uint32_t *node = (grub_uint32_t *) rec->data; + found = grub_be_to_cpu32 (*node); + } + else /* The key can not be found in the tree. */ + return 1; + + /* Check if this node is a leaf node. */ + if (hnd->type == GRUB_HFS_NODE_LEAF) + { + isleaf = 1; + + /* Found it!!!! */ + if (cmp == 0) + { + done = 1; + + grub_memcpy (datar, rec->data, + rec->datalen < datalen ? rec->datalen : datalen); + return 1; + } + } + + return 0; + } + + do + { + found = -1; + + if (grub_hfs_iterate_records (data, type, idx, 0, node_found)) + return 0; + + if (found == -1) + return 0; + + idx = found; + } while (! isleaf); + + return done; +} + + +/* Iterate over the directory with the id DIR. The tree is searched + starting with the node ROOT_IDX. For every entry in this directory + call HOOK. */ +static grub_err_t +grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, + unsigned int dir, int (*hook) (struct grub_hfs_record *)) +{ + int found = -1; + int isleaf = 0; + int next = 0; + + /* The lowest key possible with DIR as root directory. */ + struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""}; + + auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); + auto int it_dir (struct grub_hfs_node * __attribute ((unused)), + struct grub_hfs_record *); + + + int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) + { + struct grub_hfs_catalog_key *ckey = rec->key; + + if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0) + found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data); + + if (hnd->type == 0xFF && ckey->strlen > 0) + { + isleaf = 1; + next = grub_be_to_cpu32 (hnd->next); + + /* An entry was found. */ + if (grub_be_to_cpu32 (ckey->parent_dir) == dir) + return hook (rec); + } + + return 0; + } + + int it_dir (struct grub_hfs_node *hnd __attribute ((unused)), + struct grub_hfs_record *rec) + { + struct grub_hfs_catalog_key *ckey = rec->key; + struct grub_hfs_catalog_key *origkey = &key; + + /* Stop when the entries do not match anymore. */ + if (grub_be_to_cpu32 (ckey->parent_dir) + != grub_be_to_cpu32 ((origkey)->parent_dir)) + return 1; + + return hook (rec); + } + + do + { + found = -1; + + if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found)) + return grub_errno; + + if (found == -1) + return 0; + + root_idx = found; + } while (! isleaf); + + /* If there was a matching record in this leaf node, continue the + iteration until the last record was found. */ + grub_hfs_iterate_records (data, 0, next, 1, it_dir); + return grub_errno; +} + + +/* Find a file or directory with the pathname PATH in the filesystem + DATA. Return the file record in RETDATA when it is non-zero. + Return the directory number in RETINODE when it is non-zero. */ +static grub_err_t +grub_hfs_find_dir (struct grub_hfs_data *data, const char *path, + struct grub_hfs_filerec *retdata, int *retinode) +{ + int inode = data->rootdir; + char *next; + char *origpath; + struct grub_hfs_filerec frec; + struct grub_hfs_dirrec *dir = (struct grub_hfs_dirrec *) &frec; + frec.type = GRUB_HFS_FILETYPE_DIR; + + if (path[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return 0; + } + + origpath = grub_strdup (path); + if (!origpath) + return grub_errno; + + path = origpath; + path++; + + while (path && grub_strlen (path)) + { + if (frec.type != GRUB_HFS_FILETYPE_DIR) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + goto fail; + } + + /* Isolate a part of the path. */ + next = grub_strchr (path, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + struct grub_hfs_catalog_key key; + + key.parent_dir = grub_cpu_to_be32 (inode); + key.strlen = grub_strlen (path); + grub_strcpy ((char *) (key.str), path); + + /* Lookup this node. */ + if (! grub_hfs_find_node (data, (char *) &key, data->cat_root, + 0, (char *) &frec, sizeof (frec))) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + goto fail; + } + + if (grub_errno) + goto fail; + + inode = grub_be_to_cpu32 (dir->dirid); + path = next; + } + + if (retdata) + grub_memcpy (retdata, &frec, sizeof (frec)); + + if (retinode) + *retinode = inode; + + fail: + grub_free (origpath); + return grub_errno; +} + + + +static grub_err_t +grub_hfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + int inode; + + auto int dir_hook (struct grub_hfs_record *rec); + + int dir_hook (struct grub_hfs_record *rec) + { + char fname[32] = { 0 }; + char *filetype = rec->data; + struct grub_hfs_catalog_key *ckey = rec->key; + + grub_strncpy (fname, (char *) (ckey->str), ckey->strlen); + + if (*filetype == GRUB_HFS_FILETYPE_DIR) + return hook (fname, 1); + else if (*filetype == GRUB_HFS_FILETYPE_FILE) + return hook (fname, 0); + return 0; + } + + struct grub_hfs_data *data; + struct grub_hfs_filerec frec; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_hfs_mount (device->disk); + if (!data) + goto fail; + + /* First the directory ID for the directory. */ + if (grub_hfs_find_dir (data, path, &frec, &inode)) + goto fail; + + if (frec.type != GRUB_HFS_FILETYPE_DIR) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + goto fail; + } + + grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook); + + fail: + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_hfs_open (struct grub_file *file, const char *name) +{ + struct grub_hfs_data *data; + struct grub_hfs_filerec frec; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_hfs_mount (file->device->disk); + + if (grub_hfs_find_dir (data, name, &frec, 0)) + { + grub_free (data); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return grub_errno; + } + + if (frec.type != GRUB_HFS_FILETYPE_FILE) + { + grub_free (data); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a file"); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return grub_errno; + } + + grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t)); + file->size = grub_be_to_cpu32 (frec.size); + data->size = grub_be_to_cpu32 (frec.size); + data->fileid = grub_be_to_cpu32 (frec.fileid); + file->offset = 0; + + file->data = data; + + return 0; +} + +static grub_ssize_t +grub_hfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_hfs_data *data = + (struct grub_hfs_data *) file->data; + + return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf); +} + + +static grub_err_t +grub_hfs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return 0; +} + + +static grub_err_t +grub_hfs_label (grub_device_t device, char **label) +{ + struct grub_hfs_data *data; + + data = grub_hfs_mount (device->disk); + + if (data) + *label = grub_strndup ((char *) (data->sblock.volname + 1), + *data->sblock.volname); + else + *label = 0; + + grub_free (data); + return grub_errno; +} + + + +static struct grub_fs grub_hfs_fs = + { + .name = "hfs", + .dir = grub_hfs_dir, + .open = grub_hfs_open, + .read = grub_hfs_read, + .close = grub_hfs_close, + .label = grub_hfs_label, + .next = 0 + }; + +GRUB_MOD_INIT(hfs) +{ + grub_fs_register (&grub_hfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(hfs) +{ + grub_fs_unregister (&grub_hfs_fs); +} diff --git a/fs/hfsplus.c b/fs/hfsplus.c new file mode 100644 index 0000000..7022f98 --- /dev/null +++ b/fs/hfsplus.c @@ -0,0 +1,975 @@ +/* hfsplus.c - HFS+ Filesystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_HFSPLUS_MAGIC 0x482B +#define GRUB_HFSPLUSX_MAGIC 0x4858 +#define GRUB_HFSPLUS_SBLOCK 2 + +/* A HFS+ extent. */ +struct grub_hfsplus_extent +{ + /* The first block of a file on disk. */ + grub_uint32_t start; + /* The amount of blocks described by this extent. */ + grub_uint32_t count; +} __attribute__ ((packed)); + +/* The descriptor of a fork. */ +struct grub_hfsplus_forkdata +{ + grub_uint64_t size; + grub_uint32_t clumpsize; + grub_uint32_t blocks; + struct grub_hfsplus_extent extents[8]; +} __attribute__ ((packed)); + +/* The HFS+ Volume Header. */ +struct grub_hfsplus_volheader +{ + grub_uint16_t magic; + grub_uint16_t version; + grub_uint32_t attributes; + grub_uint8_t unused[32]; + grub_uint32_t blksize; + grub_uint8_t unused2[68]; + struct grub_hfsplus_forkdata allocations_file; + struct grub_hfsplus_forkdata extents_file; + struct grub_hfsplus_forkdata catalog_file; + struct grub_hfsplus_forkdata attrib_file; + struct grub_hfsplus_forkdata startup_file; +} __attribute__ ((packed)); + +/* The type of node. */ +enum grub_hfsplus_btnode_type + { + GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1, + GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0, + GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1, + GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2, + }; + +struct grub_hfsplus_btnode +{ + grub_uint32_t next; + grub_uint32_t prev; + grub_int8_t type; + grub_uint8_t height; + grub_uint16_t count; + grub_uint16_t unused; +} __attribute__ ((packed)); + +/* The header of a HFS+ B+ Tree. */ +struct grub_hfsplus_btheader +{ + grub_uint16_t depth; + grub_uint32_t root; + grub_uint32_t leaf_records; + grub_uint32_t first_leaf_node; + grub_uint32_t last_leaf_node; + grub_uint16_t nodesize; + grub_uint16_t keysize; +} __attribute__ ((packed)); + +/* The on disk layout of a catalog key. */ +struct grub_hfsplus_catkey +{ + grub_uint16_t keylen; + grub_uint32_t parent; + grub_uint16_t namelen; + grub_uint16_t name[30]; +} __attribute__ ((packed)); + +/* The on disk layout of an extent overflow file key. */ +struct grub_hfsplus_extkey +{ + grub_uint16_t keylen; + grub_uint8_t type; + grub_uint8_t unused; + grub_uint32_t fileid; + grub_uint32_t start; +} __attribute__ ((packed)); + +struct grub_hfsplus_key +{ + union + { + struct grub_hfsplus_extkey extkey; + struct grub_hfsplus_catkey catkey; + grub_uint16_t keylen; + }; +} __attribute__ ((packed)); + +struct grub_hfsplus_catfile +{ + grub_uint16_t type; + grub_uint16_t flags; + grub_uint32_t reserved; + grub_uint32_t fileid; + grub_uint8_t unused1[30]; + grub_uint16_t mode; + grub_uint8_t unused2[44]; + struct grub_hfsplus_forkdata data; + struct grub_hfsplus_forkdata resource; +} __attribute__ ((packed)); + +/* Filetype information as used in inodes. */ +#define GRUB_HFSPLUS_FILEMODE_MASK 0170000 +#define GRUB_HFSPLUS_FILEMODE_REG 0100000 +#define GRUB_HFSPLUS_FILEMODE_DIRECTORY 0040000 +#define GRUB_HFSPLUS_FILEMODE_SYMLINK 0120000 + +/* Some pre-defined file IDs. */ +#define GRUB_HFSPLUS_FILEID_ROOTDIR 2 +#define GRUB_HFSPLUS_FILEID_OVERFLOW 3 +#define GRUB_HFSPLUS_FILEID_CATALOG 4 + +enum grub_hfsplus_filetype + { + GRUB_HFSPLUS_FILETYPE_DIR = 1, + GRUB_HFSPLUS_FILETYPE_REG = 2, + GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3, + GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4 + }; + +/* Internal representation of a catalog key. */ +struct grub_hfsplus_catkey_internal +{ + int parent; + char *name; +}; + +/* Internal representation of an extent overflow key. */ +struct grub_hfsplus_extkey_internal +{ + grub_uint32_t fileid; + grub_uint32_t start; +}; + +struct grub_hfsplus_key_internal +{ + union + { + struct grub_hfsplus_extkey_internal extkey; + struct grub_hfsplus_catkey_internal catkey; + }; +}; + + + +struct grub_fshelp_node +{ + struct grub_hfsplus_data *data; + struct grub_hfsplus_extent extents[8]; + grub_uint64_t size; + grub_uint32_t fileid; +}; + +struct grub_hfsplus_btree +{ + grub_uint32_t root; + int nodesize; + + /* Catalog file node. */ + struct grub_fshelp_node file; +}; + +/* Information about a "mounted" HFS+ filesystem. */ +struct grub_hfsplus_data +{ + struct grub_hfsplus_volheader volheader; + grub_disk_t disk; + + unsigned int log2blksize; + + struct grub_hfsplus_btree catalog_tree; + struct grub_hfsplus_btree extoverflow_tree; + + struct grub_fshelp_node dirroot; + struct grub_fshelp_node opened_file; + + /* This is the offset into the physical disk for an embedded HFS+ + filesystem (one inside a plain HFS wrapper). */ + int embedded_offset; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +/* Return the offset of the record with the index INDEX, in the node + NODE which is part of the B+ tree BTREE. */ +static inline unsigned int +grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_btnode *node, int index) +{ + char *cnode = (char *) node; + grub_uint16_t *recptr; + recptr = (grub_uint16_t *) (&cnode[btree->nodesize + - index * sizeof (grub_uint16_t) - 2]); + return grub_be_to_cpu16 (*recptr); +} + +/* Return a pointer to the record with the index INDEX, in the node + NODE which is part of the B+ tree BTREE. */ +static inline struct grub_hfsplus_key * +grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_btnode *node, int index) +{ + char *cnode = (char *) node; + unsigned int offset; + offset = grub_hfsplus_btree_recoffset (btree, node, index); + return (struct grub_hfsplus_key *) &cnode[offset]; +} + + +/* Find the extent that points to FILEBLOCK. If it is not in one of + the 8 extents described by EXTENT, return -1. In that case set + FILEBLOCK to the next block. */ +static int +grub_hfsplus_find_block (struct grub_hfsplus_extent *extent, + int *fileblock) +{ + int i; + grub_size_t blksleft = *fileblock; + + /* First lookup the file in the given extents. */ + for (i = 0; i < 8; i++) + { + if (blksleft < grub_be_to_cpu32 (extent[i].count)) + return grub_be_to_cpu32 (extent[i].start) + blksleft; + blksleft -= grub_be_to_cpu32 (extent[i].count); + } + + *fileblock = blksleft; + return -1; +} + +static grub_err_t +grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_key_internal *key, + int (*compare_keys) (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb), + struct grub_hfsplus_btnode **matchnode, int *keyoffset); + +static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb); + +/* Search for the block FILEBLOCK inside the file NODE. Return the + blocknumber of this block on disk. */ +static grub_disk_addr_t +grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_hfsplus_btnode *nnode = 0; + int blksleft = fileblock; + struct grub_hfsplus_extent *extents = &node->extents[0]; + + while (1) + { + struct grub_hfsplus_extkey *key; + struct grub_hfsplus_extkey_internal extoverflow; + int blk; + int ptr; + + /* Try to find this block in the current set of extents. */ + blk = grub_hfsplus_find_block (extents, &blksleft); + + /* The previous iteration of this loop allocated memory. The + code above used this memory, it can be freed now. */ + grub_free (nnode); + nnode = 0; + + if (blk != -1) + return (blk + + (node->data->embedded_offset >> (node->data->log2blksize + - GRUB_DISK_SECTOR_BITS))); + + /* For the extent overflow file, extra extents can't be found in + the extent overflow file. If this happens, you found a + bug... */ + if (node->fileid == GRUB_HFSPLUS_FILEID_OVERFLOW) + { + grub_error (GRUB_ERR_READ_ERROR, + "extra extents found in an extend overflow file"); + break; + } + + /* Set up the key to look for in the extent overflow file. */ + extoverflow.fileid = node->fileid; + extoverflow.start = fileblock - blksleft; + + if (grub_hfsplus_btree_search (&node->data->extoverflow_tree, + (struct grub_hfsplus_key_internal *) &extoverflow, + grub_hfsplus_cmp_extkey, &nnode, &ptr)) + { + grub_error (GRUB_ERR_READ_ERROR, + "no block found for the file id 0x%x and the block offset 0x%x", + node->fileid, fileblock); + break; + } + + /* The extent overflow file has 8 extents right after the key. */ + key = (struct grub_hfsplus_extkey *) + grub_hfsplus_btree_recptr (&node->data->extoverflow_tree, nnode, ptr); + extents = (struct grub_hfsplus_extent *) (key + 1); + + /* The block wasn't found. Perhaps the next iteration will find + it. The last block we found is stored in BLKSLEFT now. */ + } + + grub_free (nnode); + + /* Too bad, you lose. */ + return -1; +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_hfsplus_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_hfsplus_read_block, + node->size, + node->data->log2blksize - GRUB_DISK_SECTOR_BITS); +} + +static struct grub_hfsplus_data * +grub_hfsplus_mount (grub_disk_t disk) +{ + struct grub_hfsplus_data *data; + struct grub_hfsplus_btheader header; + struct grub_hfsplus_btnode node; + union { + struct grub_hfs_sblock hfs; + struct grub_hfsplus_volheader hfsplus; + } volheader; + + data = grub_malloc (sizeof (*data)); + if (!data) + return 0; + + data->disk = disk; + + /* Read the bootblock. */ + grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader), + (char *) &volheader); + if (grub_errno) + goto fail; + + data->embedded_offset = 0; + if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC) + { + int extent_start; + int ablk_size; + int ablk_start; + + /* See if there's an embedded HFS+ filesystem. */ + if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC) + { + grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); + goto fail; + } + + /* Calculate the offset needed to translate HFS+ sector numbers. */ + extent_start = grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block); + ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz); + ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block); + data->embedded_offset = (ablk_start + + extent_start + * (ablk_size >> GRUB_DISK_SECTOR_BITS)); + + grub_disk_read (disk, data->embedded_offset + GRUB_HFSPLUS_SBLOCK, 0, + sizeof (volheader), (char *) &volheader); + if (grub_errno) + goto fail; + } + + /* Make sure this is an HFS+ filesystem. XXX: Do we really support + HFX? */ + if ((grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUS_MAGIC) + && (grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUSX_MAGIC)) + { + grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); + goto fail; + } + + grub_memcpy (&data->volheader, &volheader.hfsplus, + sizeof (volheader.hfsplus)); + + if (grub_fshelp_log2blksize (grub_be_to_cpu32 (data->volheader.blksize), + &data->log2blksize)) + goto fail; + + /* Make a new node for the catalog tree. */ + data->catalog_tree.file.data = data; + data->catalog_tree.file.fileid = GRUB_HFSPLUS_FILEID_CATALOG; + grub_memcpy (&data->catalog_tree.file.extents, + data->volheader.catalog_file.extents, + sizeof data->volheader.catalog_file.extents); + data->catalog_tree.file.size = + grub_be_to_cpu64 (data->volheader.catalog_file.size); + + /* Make a new node for the extent overflow file. */ + data->extoverflow_tree.file.data = data; + data->extoverflow_tree.file.fileid = GRUB_HFSPLUS_FILEID_OVERFLOW; + grub_memcpy (&data->extoverflow_tree.file.extents, + data->volheader.extents_file.extents, + sizeof data->volheader.catalog_file.extents); + + data->extoverflow_tree.file.size = + grub_be_to_cpu64 (data->volheader.extents_file.size); + + /* Read the essential information about the trees. */ + if (! grub_hfsplus_read_file (&data->catalog_tree.file, 0, + sizeof (struct grub_hfsplus_btnode), + sizeof (header), (char *) &header)) + goto fail; + + data->catalog_tree.root = grub_be_to_cpu32 (header.root); + data->catalog_tree.nodesize = grub_be_to_cpu16 (header.nodesize); + + if (! grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, + sizeof (struct grub_hfsplus_btnode), + sizeof (header), (char *) &header)) + goto fail; + + data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); + + if (! grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, + sizeof (node), (char *) &node)) + goto fail; + + data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); + data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize); + + data->dirroot.data = data; + data->dirroot.fileid = GRUB_HFSPLUS_FILEID_ROOTDIR; + + return data; + + fail: + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a hfsplus filesystem"); + + grub_free (data); + return 0; +} + +/* Compare the on disk catalog key KEYA with the catalog key we are + looking for (KEYB). */ +static int +grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb) +{ + struct grub_hfsplus_catkey *catkey_a = &keya->catkey; + struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; + char *filename; + int i; + int diff; + + diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent; + if (diff) + return diff; + + /* Change the filename in keya so the endianness is correct. */ + for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) + catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]); + + filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1); + + if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name, + grub_be_to_cpu16 (catkey_a->namelen))) + return -1; /* XXX: This error never occurs, but in case it happens + just skip this entry. */ + + diff = grub_strncmp (filename, catkey_b->name, + grub_be_to_cpu16 (catkey_a->namelen)); + + grub_free (filename); + + /* The endianness was changed to host format, change it back to + whatever it was. */ + for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) + catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]); + return diff; +} + +/* Compare the on disk extent overflow key KEYA with the extent + overflow key we are looking for (KEYB). */ +static int +grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb) +{ + struct grub_hfsplus_extkey *extkey_a = &keya->extkey; + struct grub_hfsplus_extkey_internal *extkey_b = &keyb->extkey; + int diff; + + diff = grub_be_to_cpu32 (extkey_a->fileid) - extkey_b->fileid; + + if (diff) + return diff; + + diff = grub_be_to_cpu32 (extkey_a->start) - extkey_b->start; + return diff; +} + +static char * +grub_hfsplus_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + grub_ssize_t numread; + + symlink = grub_malloc (node->size + 1); + if (!symlink) + return 0; + + numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink); + if (numread != (grub_ssize_t) node->size) + { + grub_free (symlink); + return 0; + } + symlink[node->size] = '\0'; + + return symlink; +} + +static int +grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_btnode *first_node, + int first_rec, + int (*hook) (void *record)) +{ + int rec; + + for (;;) + { + char *cnode = (char *) first_node; + + /* Iterate over all records in this node. */ + for (rec = first_rec; rec < grub_be_to_cpu16 (first_node->count); rec++) + { + if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec))) + return 1; + } + + if (! first_node->next) + break; + + if (! grub_hfsplus_read_file (&btree->file, 0, + (grub_be_to_cpu32 (first_node->next) + * btree->nodesize), + btree->nodesize, cnode)) + return 1; + + /* Don't skip any record in the next iteration. */ + first_rec = 0; + } + + return 0; +} + +/* Lookup the node described by KEY in the B+ Tree BTREE. Compare + keys using the function COMPARE_KEYS. When a match is found, + return the node in MATCHNODE and a pointer to the data in this node + in KEYOFFSET. MATCHNODE should be freed by the caller. */ +static grub_err_t +grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_key_internal *key, + int (*compare_keys) (struct grub_hfsplus_key *keya, + struct grub_hfsplus_key_internal *keyb), + struct grub_hfsplus_btnode **matchnode, int *keyoffset) +{ + grub_uint64_t currnode; + char *node; + struct grub_hfsplus_btnode *nodedesc; + int rec; + + node = grub_malloc (btree->nodesize); + if (! node) + return grub_errno; + + currnode = btree->root; + while (1) + { + int match = 0; + + /* Read a node. */ + if (! grub_hfsplus_read_file (&btree->file, 0, + (long)currnode * (long)btree->nodesize, + btree->nodesize, (char *) node)) + { + grub_free (node); + return grub_errno; + } + + nodedesc = (struct grub_hfsplus_btnode *) node; + + /* Find the record in this tree. */ + for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++) + { + struct grub_hfsplus_key *currkey; + currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec); + + /* The action that has to be taken depend on the type of + record. */ + if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF + && compare_keys (currkey, key) == 0) + { + /* An exact match was found! */ + + *matchnode = nodedesc; + *keyoffset = rec; + + return 0; + } + else if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_INDEX) + { + grub_uint32_t *pointer; + + /* The place where the key could have been found didn't + contain the key. This means that the previous match + is the one that should be followed. */ + if (compare_keys (currkey, key) > 0) + break; + + /* Mark the last key which is lower or equal to the key + that we are looking for. The last match that is + found will be used to locate the child which can + contain the record. */ + pointer = (grub_uint32_t *) ((char *) currkey + + grub_be_to_cpu16 (currkey->keylen) + + 2); + currnode = grub_be_to_cpu32 (*pointer); + match = 1; + } + } + + /* No match is found, no record with this key exists in the + tree. */ + if (! match) + { + *matchnode = 0; + grub_free (node); + return 1; + } + } +} + +static int +grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + int ret = 0; + + auto int list_nodes (void *record); + int list_nodes (void *record) + { + struct grub_hfsplus_catkey *catkey; + char *filename; + int i; + struct grub_fshelp_node *node; + struct grub_hfsplus_catfile *fileinfo; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + catkey = (struct grub_hfsplus_catkey *) record; + + fileinfo = + (struct grub_hfsplus_catfile *) ((char *) record + + grub_be_to_cpu16 (catkey->keylen) + + 2 + (grub_be_to_cpu16(catkey->keylen) + % 2)); + + /* Stop iterating when the last directory entry is found. */ + if (grub_be_to_cpu32 (catkey->parent) != dir->fileid) + return 1; + + /* Determine the type of the node that is found. */ + if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_REG) + { + int mode = (grub_be_to_cpu16 (fileinfo->mode) + & GRUB_HFSPLUS_FILEMODE_MASK); + + if (mode == GRUB_HFSPLUS_FILEMODE_REG) + type = GRUB_FSHELP_REG; + else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else + type = GRUB_FSHELP_UNKNOWN; + } + else if (grub_be_to_cpu16 (fileinfo->type) == GRUB_HFSPLUS_FILETYPE_DIR) + type = GRUB_FSHELP_DIR; + + if (type == GRUB_FSHELP_UNKNOWN) + return 0; + + /* Make sure the byte order of the UTF16 string is correct. */ + for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) + { + catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + + /* If the name is obviously invalid, skip this node. */ + if (catkey->name[i] == 0) + return 0; + } + + filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1); + if (! filename) + return 0; + + if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, + grub_be_to_cpu16 (catkey->namelen))) + { + grub_free (filename); + return 0; + } + + filename[grub_be_to_cpu16 (catkey->namelen)] = '\0'; + + /* Restore the byte order to what it was previously. */ + for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) + catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + + /* hfs+ is case insensitive. */ + type |= GRUB_FSHELP_CASE_INSENSITIVE; + + /* Only accept valid nodes. */ + if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen)) + { + /* A valid node is found; setup the node and call the + callback function. */ + node = grub_malloc (sizeof (*node)); + node->data = dir->data; + + grub_memcpy (node->extents, fileinfo->data.extents, + sizeof (node->extents)); + node->size = grub_be_to_cpu64 (fileinfo->data.size); + node->fileid = grub_be_to_cpu32 (fileinfo->fileid); + + ret = hook (filename, type, node); + } + + grub_free (filename); + + return ret; + } + + struct grub_hfsplus_key_internal intern; + struct grub_hfsplus_btnode *node; + int ptr; + + /* Create a key that points to the first entry in the directory. */ + intern.catkey.parent = dir->fileid; + intern.catkey.name = ""; + + /* First lookup the first entry. */ + if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern, + grub_hfsplus_cmp_catkey, &node, &ptr)) + return 0; + + /* Iterate over all entries in this directory. */ + grub_hfsplus_btree_iterate_node (&dir->data->catalog_tree, node, ptr, + list_nodes); + + grub_free (node); + + return ret; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_hfsplus_open (struct grub_file *file, const char *name) +{ + struct grub_hfsplus_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_hfsplus_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->dirroot, &fdiro, + grub_hfsplus_iterate_dir, + grub_hfsplus_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + file->size = fdiro->size; + data->opened_file = *fdiro; + grub_free (fdiro); + + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (data && fdiro != &data->dirroot) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_hfsplus_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_hfsplus_data *data = + (struct grub_hfsplus_data *) file->data; + + int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook, + file->offset, len, buf); + + return size; +} + + +static grub_err_t +grub_hfsplus_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_hfsplus_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_hfsplus_mount (device->disk); + if (!data) + goto fail; + + /* Find the directory that should be opened. */ + grub_fshelp_find_file (path, &data->dirroot, &fdiro, + grub_hfsplus_iterate_dir, + grub_hfsplus_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + /* Iterate over all entries in this directory. */ + grub_hfsplus_iterate_dir (fdiro, iterate); + + fail: + if (data && fdiro != &data->dirroot) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_hfsplus_label (grub_device_t device __attribute__((unused)) + , char **label __attribute__((unused))) +{ + /* XXX: It's not documented how to read a label. */ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "reading the label of a HFS+ " + "partition is not implemented"); +} + + +static struct grub_fs grub_hfsplus_fs = + { + .name = "hfsplus", + .dir = grub_hfsplus_dir, + .open = grub_hfsplus_open, + .read = grub_hfsplus_read, + .close = grub_hfsplus_close, + .label = grub_hfsplus_label, + .next = 0 + }; + +GRUB_MOD_INIT(hfsplus) +{ + grub_fs_register (&grub_hfsplus_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(hfsplus) +{ + grub_fs_unregister (&grub_hfsplus_fs); +} diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c new file mode 100644 index 0000000..e12ca18 --- /dev/null +++ b/fs/i386/pc/pxe.c @@ -0,0 +1,321 @@ +/* pxe.c - Driver to provide access to the pxe filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define SEGMENT(x) ((x) >> 4) +#define OFFSET(x) ((x) & 0xF) +#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) +#define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF)) + +struct grub_pxenv *grub_pxe_pxenv; +grub_uint32_t grub_pxe_your_ip; +grub_uint32_t grub_pxe_server_ip; +grub_uint32_t grub_pxe_gateway_ip; +int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; + +static grub_file_t curr_file = 0; + +struct grub_pxe_data +{ + grub_uint32_t packet_number; + grub_uint32_t block_size; + char filename[0]; +}; + +static int +grub_pxe_iterate (int (*hook) (const char *name)) +{ + if (hook ("pxe")) + return 1; + return 0; +} + +static grub_err_t +grub_pxe_open (const char *name, grub_disk_t disk) +{ + if (grub_strcmp (name, "pxe")) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk"); + + disk->total_sectors = 0; + disk->id = (unsigned long) "pxe"; + + disk->has_partitions = 0; + disk->data = 0; + + return GRUB_ERR_NONE; +} + +static void +grub_pxe_close (grub_disk_t disk __attribute((unused))) +{ +} + +static grub_err_t +grub_pxe_read (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + char *buf __attribute((unused))) +{ + return GRUB_ERR_OUT_OF_RANGE; +} + +static grub_err_t +grub_pxe_write (grub_disk_t disk __attribute((unused)), + grub_disk_addr_t sector __attribute((unused)), + grub_size_t size __attribute((unused)), + const char *buf __attribute((unused))) +{ + return GRUB_ERR_OUT_OF_RANGE; +} + +static struct grub_disk_dev grub_pxe_dev = + { + .name = "pxe", + .id = GRUB_DISK_DEVICE_PXE_ID, + .iterate = grub_pxe_iterate, + .open = grub_pxe_open, + .close = grub_pxe_close, + .read = grub_pxe_read, + .write = grub_pxe_write, + .next = 0 + }; + +static grub_err_t +grub_pxefs_dir (grub_device_t device __attribute((unused)), + const char *path __attribute((unused)), + int (*hook) (const char *filename, int dir) __attribute((unused))) +{ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_pxefs_open (struct grub_file *file, const char *name) +{ + union + { + struct grub_pxenv_tftp_get_fsize c1; + struct grub_pxenv_tftp_open c2; + } c; + struct grub_pxe_data *data; + grub_file_t file_int, bufio; + + if (curr_file != 0) + { + grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2); + curr_file = 0; + } + + c.c1.server_ip = grub_pxe_server_ip; + c.c1.gateway_ip = grub_pxe_gateway_ip; + grub_strcpy ((char *)&c.c1.filename[0], name); + grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1); + if (c.c1.status) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + + file->size = c.c1.file_size; + + c.c2.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); + c.c2.packet_size = grub_pxe_blksize; + grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &c.c2); + if (c.c2.status) + return grub_error (GRUB_ERR_BAD_FS, "open fails"); + + data = grub_malloc (sizeof (struct grub_pxe_data) + grub_strlen (name) + 1); + if (! data) + return grub_errno; + + data->packet_number = 0; + data->block_size = grub_pxe_blksize; + grub_strcpy (data->filename, name); + + file_int = grub_malloc (sizeof (*file_int)); + if (! file_int) + { + grub_free (data); + return grub_errno; + } + + file->data = data; + grub_memcpy (file_int, file, sizeof (struct grub_file)); + curr_file = file_int; + + bufio = grub_bufio_open (file_int, data->block_size); + if (! bufio) + { + grub_free (file_int); + grub_free (data); + return grub_errno; + } + + grub_memcpy (file, bufio, sizeof (struct grub_file)); + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_pxenv_tftp_read c; + struct grub_pxe_data *data; + grub_uint32_t pn, r; + + data = file->data; + + pn = grub_divmod64 (file->offset, data->block_size, &r); + if (r) + return grub_error (GRUB_ERR_BAD_FS, + "read access must be aligned to packet size"); + + if ((curr_file != file) || (data->packet_number > pn)) + { + struct grub_pxenv_tftp_open o; + + if (curr_file != 0) + grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o); + + o.server_ip = grub_pxe_server_ip; + o.gateway_ip = grub_pxe_gateway_ip; + grub_strcpy ((char *)&o.filename[0], data->filename); + o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); + o.packet_size = data->block_size; + grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o); + if (o.status) + return grub_error (GRUB_ERR_BAD_FS, "open fails"); + data->packet_number = 0; + curr_file = file; + } + + c.buffer = SEGOFS (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); + while (pn >= data->packet_number) + { + c.buffer_size = grub_pxe_blksize; + grub_pxe_call (GRUB_PXENV_TFTP_READ, &c); + if (c.status) + { + grub_error (GRUB_ERR_BAD_FS, "read fails"); + return -1; + } + data->packet_number++; + } + + grub_memcpy (buf, (char *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, len); + + return len; +} + +static grub_err_t +grub_pxefs_close (grub_file_t file) +{ + struct grub_pxenv_tftp_close c; + + if (curr_file == file) + { + grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c); + curr_file = 0; + } + + grub_free (file->data); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_pxefs_label (grub_device_t device __attribute ((unused)), + char **label __attribute ((unused))) +{ + *label = 0; + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_pxefs_fs = + { + .name = "pxefs", + .dir = grub_pxefs_dir, + .open = grub_pxefs_open, + .read = grub_pxefs_read, + .close = grub_pxefs_close, + .label = grub_pxefs_label, + .next = 0 + }; + +static void +grub_pxe_detect (void) +{ + struct grub_pxenv *pxenv; + struct grub_pxenv_get_cached_info ci; + struct grub_pxenv_boot_player *bp; + + pxenv = grub_pxe_scan (); + if (! pxenv) + return; + + ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK; + ci.buffer = 0; + ci.buffer_size = 0; + grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci); + if (ci.status) + return; + + bp = LINEAR (ci.buffer); + + grub_pxe_your_ip = bp->your_ip; + grub_pxe_server_ip = bp->server_ip; + grub_pxe_gateway_ip = bp->gateway_ip; + + grub_pxe_pxenv = pxenv; +} + +void +grub_pxe_unload (void) +{ + if (grub_pxe_pxenv) + { + grub_fs_unregister (&grub_pxefs_fs); + grub_disk_dev_unregister (&grub_pxe_dev); + + grub_pxe_pxenv = 0; + } +} + +GRUB_MOD_INIT(pxe) +{ + (void) mod; /* To stop warning. */ + + grub_pxe_detect (); + if (grub_pxe_pxenv) + { + grub_disk_dev_register (&grub_pxe_dev); + grub_fs_register (&grub_pxefs_fs); + } +} + +GRUB_MOD_FINI(pxe) +{ + grub_pxe_unload (); +} diff --git a/fs/iso9660.c b/fs/iso9660.c new file mode 100644 index 0000000..6db2283 --- /dev/null +++ b/fs/iso9660.c @@ -0,0 +1,907 @@ +/* iso9660.c - iso9660 implementation with extensions: + SUSP, Rock Ridge. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_ISO9660_FSTYPE_DIR 0040000 +#define GRUB_ISO9660_FSTYPE_REG 0100000 +#define GRUB_ISO9660_FSTYPE_SYMLINK 0120000 +#define GRUB_ISO9660_FSTYPE_MASK 0170000 + +#define GRUB_ISO9660_LOG2_BLKSZ 2 +#define GRUB_ISO9660_BLKSZ 2048 + +#define GRUB_ISO9660_RR_DOT 2 +#define GRUB_ISO9660_RR_DOTDOT 4 + +#define GRUB_ISO9660_VOLDESC_BOOT 0 +#define GRUB_ISO9660_VOLDESC_PRIMARY 1 +#define GRUB_ISO9660_VOLDESC_SUPP 2 +#define GRUB_ISO9660_VOLDESC_PART 3 +#define GRUB_ISO9660_VOLDESC_END 255 + +/* The head of a volume descriptor. */ +struct grub_iso9660_voldesc +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} __attribute__ ((packed)); + +/* A directory entry. */ +struct grub_iso9660_dir +{ + grub_uint8_t len; + grub_uint8_t ext_sectors; + grub_uint32_t first_sector; + grub_uint32_t first_sector_be; + grub_uint32_t size; + grub_uint32_t size_be; + grub_uint8_t unused1[7]; + grub_uint8_t flags; + grub_uint8_t unused2[6]; + grub_uint8_t namelen; +} __attribute__ ((packed)); + +struct grub_iso9660_date +{ + grub_uint8_t year[4]; + grub_uint8_t month[2]; + grub_uint8_t day[2]; + grub_uint8_t hour[2]; + grub_uint8_t minute[2]; + grub_uint8_t second[2]; + grub_uint8_t hundredth[2]; + grub_uint8_t offset; +} __attribute__ ((packed)); + +/* The primary volume descriptor. Only little endian is used. */ +struct grub_iso9660_primary_voldesc +{ + struct grub_iso9660_voldesc voldesc; + grub_uint8_t unused1[33]; + grub_uint8_t volname[32]; + grub_uint8_t unused2[16]; + grub_uint8_t escape[32]; + grub_uint8_t unused3[12]; + grub_uint32_t path_table_size; + grub_uint8_t unused4[4]; + grub_uint32_t path_table; + grub_uint8_t unused5[12]; + struct grub_iso9660_dir rootdir; + grub_uint8_t unused6[624]; + struct grub_iso9660_date created; + struct grub_iso9660_date modified; +} __attribute__ ((packed)); + +/* A single entry in the path table. */ +struct grub_iso9660_path +{ + grub_uint8_t len; + grub_uint8_t sectors; + grub_uint32_t first_sector; + grub_uint16_t parentdir; + grub_uint8_t name[0]; +} __attribute__ ((packed)); + +/* An entry in the System Usage area of the directory entry. */ +struct grub_iso9660_susp_entry +{ + grub_uint8_t sig[2]; + grub_uint8_t len; + grub_uint8_t version; + grub_uint8_t data[0]; +} __attribute__ ((packed)); + +/* The CE entry. This is used to describe the next block where data + can be found. */ +struct grub_iso9660_susp_ce +{ + struct grub_iso9660_susp_entry entry; + grub_uint32_t blk; + grub_uint32_t blk_be; + grub_uint32_t off; + grub_uint32_t off_be; + grub_uint32_t len; + grub_uint32_t len_be; +} __attribute__ ((packed)); + +struct grub_iso9660_data +{ + struct grub_iso9660_primary_voldesc voldesc; + grub_disk_t disk; + unsigned int first_sector; + unsigned int length; + int rockridge; + int susp_skip; + int joliet; +}; + +struct grub_fshelp_node +{ + struct grub_iso9660_data *data; + unsigned int size; + unsigned int blk; + unsigned int dir_blk; + unsigned int dir_off; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for + every entry. */ +static grub_err_t +grub_iso9660_susp_iterate (struct grub_iso9660_data *data, + int sua_block, int sua_pos, int sua_size, + grub_err_t (*hook) + (struct grub_iso9660_susp_entry *entry)) +{ + char *sua; + struct grub_iso9660_susp_entry *entry; + + auto grub_err_t load_sua (void); + + /* Load a part of the System Usage Area. */ + grub_err_t load_sua (void) + { + sua = grub_malloc (sua_size); + if (!sua) + return grub_errno; + + if (grub_disk_read (data->disk, sua_block, sua_pos, + sua_size, sua)) + return grub_errno; + + entry = (struct grub_iso9660_susp_entry *) sua; + return 0; + } + + if (load_sua ()) + return grub_errno; + + for (; (char *) entry < (char *) sua + sua_size - 1; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { + /* The last entry. */ + if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0) + break; + + /* Additional entries are stored elsewhere. */ + if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) + { + struct grub_iso9660_susp_ce *ce; + + ce = (struct grub_iso9660_susp_ce *) entry; + sua_size = grub_le_to_cpu32 (ce->len); + sua_pos = grub_le_to_cpu32 (ce->off); + sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + + grub_free (sua); + if (load_sua ()) + return grub_errno; + } + + if (hook (entry)) + { + grub_free (sua); + return 0; + } + } + + grub_free (sua); + return 0; +} + +static char * +grub_iso9660_convert_string (grub_uint16_t *us, int len) +{ + char *p; + int i; + + p = grub_malloc (len * 4 + 1); + if (! p) + return p; + + for (i=0; isig, "ER", 2) == 0) + { + data->rockridge = 1; + return 1; + } + return 0; + } + + data = grub_malloc (sizeof (struct grub_iso9660_data)); + if (! data) + return 0; + + data->disk = disk; + data->rockridge = 0; + data->joliet = 0; + + block = 16; + do + { + int copy_voldesc = 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, block << GRUB_ISO9660_LOG2_BLKSZ, 0, + sizeof (struct grub_iso9660_primary_voldesc), + (char *) &voldesc)) + { + grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + goto fail; + } + + if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0) + { + grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + goto fail; + } + + if (voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_PRIMARY) + copy_voldesc = 1; + else if ((voldesc.voldesc.type == GRUB_ISO9660_VOLDESC_SUPP) && + (voldesc.escape[0] == 0x25) && (voldesc.escape[1] == 0x2f) && + ((voldesc.escape[2] == 0x40) || /* UCS-2 Level 1. */ + (voldesc.escape[2] == 0x43) || /* UCS-2 Level 2. */ + (voldesc.escape[2] == 0x45))) /* UCS-2 Level 3. */ + { + copy_voldesc = 1; + data->joliet = 1; + } + + if (copy_voldesc) + grub_memcpy((char *) &data->voldesc, (char *) &voldesc, + sizeof (struct grub_iso9660_primary_voldesc)); + + block++; + } while (voldesc.voldesc.type != GRUB_ISO9660_VOLDESC_END); + + /* Read the system use area and test it to see if SUSP is + supported. */ + if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), 0, + sizeof (rootdir), (char *) &rootdir)) + { + grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + goto fail; + } + + sua_pos = (sizeof (rootdir) + rootdir.namelen + + (rootdir.namelen % 2) - 1); + sua_size = rootdir.len - sua_pos; + + sua = grub_malloc (sua_size); + if (! sua) + goto fail; + + if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, + sua_size, sua)) + { + grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + goto fail; + } + + entry = (struct grub_iso9660_susp_entry *) sua; + + /* Test if the SUSP protocol is used on this filesystem. */ + if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0) + { + /* The 2nd data byte stored how many bytes are skipped every time + to get to the SUA (System Usage Area). */ + data->susp_skip = entry->data[2]; + entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); + + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (data, + (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector) + << GRUB_ISO9660_LOG2_BLKSZ), + sua_pos, sua_size, susp_iterate)) + goto fail; + } + + return data; + + fail: + grub_free (data); + return 0; +} + + +static char * +grub_iso9660_read_symlink (grub_fshelp_node_t node) +{ + struct grub_iso9660_dir dirent; + int sua_off; + int sua_size; + char *symlink = 0; + int addslash = 0; + + auto void add_part (const char *part, int len); + auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *); + + /* Extend the symlink. */ + void add_part (const char *part, int len) + { + int size = grub_strlen (symlink); + + symlink = grub_realloc (symlink, size + len + 1); + if (! symlink) + return; + + grub_strncat (symlink, part, len); + } + + /* Read in a symlink. */ + grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry) + { + if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) + { + unsigned int pos = 1; + + /* The symlink is not stored as a POSIX symlink, translate it. */ + while (pos < grub_le_to_cpu32 (entry->len)) + { + if (addslash) + { + add_part ("/", 1); + addslash = 0; + } + + /* The current position is the `Component Flag'. */ + switch (entry->data[pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 + is the length. Both are part of the `Component + Record'. */ + add_part ((char *) &entry->data[pos + 2], + entry->data[pos + 1]); + if ((entry->data[pos] & 1)) + addslash = 1; + + break; + } + + case 2: + add_part ("./", 2); + break; + + case 4: + add_part ("../", 3); + break; + + case 8: + add_part ("/", 1); + break; + } + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->data[pos + 1] + 2; + } + + /* Check if `grub_realloc' failed. */ + if (grub_errno) + return grub_errno; + } + + return 0; + } + + if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off, + sizeof (dirent), (char *) &dirent)) + return 0; + + sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2) + + node->data->susp_skip); + sua_size = dirent.len - sua_off; + + symlink = grub_malloc (1); + if (!symlink) + return 0; + + *symlink = '\0'; + + if (grub_iso9660_susp_iterate (node->data, node->dir_blk, + node->dir_off + sua_off, + sua_size, susp_iterate_sl)) + { + grub_free (symlink); + return 0; + } + + return symlink; +} + + +static int +grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + struct grub_iso9660_dir dirent; + unsigned int offset = 0; + char *filename; + int filename_alloc = 0; + enum grub_fshelp_filetype type; + + auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); + + grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry) + { + /* The filename in the rock ridge entry. */ + if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) + { + /* The flags are stored at the data position 0, here the + filename type is stored. */ + if (entry->data[0] & GRUB_ISO9660_RR_DOT) + filename = "."; + else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) + filename = ".."; + else + { + int size = 1; + if (filename) + { + size += grub_strlen (filename); + grub_realloc (filename, + grub_strlen (filename) + + entry->len); + } + else + { + size = entry->len - 5; + filename = grub_malloc (size + 1); + filename[0] = '\0'; + } + filename_alloc = 1; + grub_strncpy (filename, (char *) &entry->data[1], size); + filename[size] = '\0'; + } + } + /* The mode information (st_mode). */ + else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) + { + /* At position 0 of the PX record the st_mode information is + stored. */ + grub_uint32_t mode = ((*(grub_uint32_t *) &entry->data[0]) + & GRUB_ISO9660_FSTYPE_MASK); + + switch (mode) + { + case GRUB_ISO9660_FSTYPE_DIR: + type = GRUB_FSHELP_DIR; + break; + case GRUB_ISO9660_FSTYPE_REG: + type = GRUB_FSHELP_REG; + break; + case GRUB_ISO9660_FSTYPE_SYMLINK: + type = GRUB_FSHELP_SYMLINK; + break; + default: + type = GRUB_FSHELP_UNKNOWN; + } + } + + return 0; + } + + while (offset < dir->size) + { + if (grub_disk_read (dir->data->disk, + (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) + + offset / GRUB_DISK_SECTOR_SIZE, + offset % GRUB_DISK_SECTOR_SIZE, + sizeof (dirent), (char *) &dirent)) + return 0; + + /* The end of the block, skip to the next one. */ + if (!dirent.len) + { + offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; + continue; + } + + { + char name[dirent.namelen + 1]; + int nameoffset = offset + sizeof (dirent); + struct grub_fshelp_node *node; + int sua_off = (sizeof (dirent) + dirent.namelen + 1 + - (dirent.namelen % 2));; + int sua_size = dirent.len - sua_off; + + sua_off += offset + dir->data->susp_skip; + + filename = 0; + filename_alloc = 0; + type = GRUB_FSHELP_UNKNOWN; + + if (dir->data->rockridge + && grub_iso9660_susp_iterate (dir->data, + (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) + + (sua_off + / GRUB_DISK_SECTOR_SIZE), + sua_off % GRUB_DISK_SECTOR_SIZE, + sua_size, susp_iterate_dir)) + return 0; + + /* Read the name. */ + if (grub_disk_read (dir->data->disk, + (dir->blk << GRUB_ISO9660_LOG2_BLKSZ) + + nameoffset / GRUB_DISK_SECTOR_SIZE, + nameoffset % GRUB_DISK_SECTOR_SIZE, + dirent.namelen, (char *) name)) + return 0; + + node = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!node) + return 0; + + /* Setup a new node. */ + node->data = dir->data; + node->size = grub_le_to_cpu32 (dirent.size); + node->blk = grub_le_to_cpu32 (dirent.first_sector); + node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ) + + offset / GRUB_DISK_SECTOR_SIZE); + node->dir_off = offset % GRUB_DISK_SECTOR_SIZE; + + /* If the filetype was not stored using rockridge, use + whatever is stored in the iso9660 filesystem. */ + if (type == GRUB_FSHELP_UNKNOWN) + { + if ((dirent.flags & 3) == 2) + type = GRUB_FSHELP_DIR; + else + type = GRUB_FSHELP_REG; + } + + /* The filename was not stored in a rock ridge entry. Read it + from the iso9660 filesystem. */ + if (!filename) + { + name[dirent.namelen] = '\0'; + filename = grub_strrchr (name, ';'); + if (filename) + *filename = '\0'; + + if (dirent.namelen == 1 && name[0] == 0) + filename = "."; + else if (dirent.namelen == 1 && name[0] == 1) + filename = ".."; + else + filename = name; + } + + if (dir->data->joliet) + { + char *oldname; + + oldname = filename; + filename = grub_iso9660_convert_string + ((grub_uint16_t *) oldname, dirent.namelen >> 1); + + if (filename_alloc) + grub_free (oldname); + + filename_alloc = 1; + } + + if (hook (filename, type, node)) + { + if (filename_alloc) + grub_free (filename); + return 1; + } + if (filename_alloc) + grub_free (filename); + } + + offset += dirent.len; + } + + return 0; +} + + + +static grub_err_t +grub_iso9660_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_iso9660_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_iso9660_mount (device->disk); + if (! data) + goto fail; + + rootnode.data = data; + rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); + rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (path, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_DIR)) + goto fail; + + /* List the files in the directory. */ + grub_iso9660_iterate_dir (foundnode, iterate); + + if (foundnode != &rootnode) + grub_free (foundnode); + + fail: + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_iso9660_open (struct grub_file *file, const char *name) +{ + struct grub_iso9660_data *data; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_iso9660_mount (file->device->disk); + if (!data) + goto fail; + + rootnode.data = data; + rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector); + rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size); + + /* Use the fshelp function to traverse the path. */ + if (grub_fshelp_find_file (name, &rootnode, + &foundnode, + grub_iso9660_iterate_dir, + grub_iso9660_read_symlink, + GRUB_FSHELP_REG)) + goto fail; + + data->first_sector = foundnode->blk; + data->length = foundnode->size; + + file->data = data; + file->size = foundnode->size; + file->offset = 0; + + return 0; + + fail: +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno;; +} + + +static grub_ssize_t +grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_iso9660_data *data = + (struct grub_iso9660_data *) file->data; + + /* XXX: The file is stored in as a single extent. */ + data->disk->read_hook = file->read_hook; + grub_disk_read (data->disk, + data->first_sector << GRUB_ISO9660_LOG2_BLKSZ, + file->offset, + len, buf); + data->disk->read_hook = 0; + + return len; +} + + +static grub_err_t +grub_iso9660_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_iso9660_label (grub_device_t device, char **label) +{ + struct grub_iso9660_data *data; + data = grub_iso9660_mount (device->disk); + + if (data) + { + if (data->joliet) + *label = grub_iso9660_convert_string + ((grub_uint16_t *) &data->voldesc.volname, 16); + else + *label = grub_strndup ((char *) data->voldesc.volname, 32); + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + + +static grub_err_t +grub_iso9660_uuid (grub_device_t device, char **uuid) +{ + struct grub_iso9660_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_iso9660_mount (disk); + if (data) + { + if (! data->voldesc.modified.year[0] && ! data->voldesc.modified.year[1] + && ! data->voldesc.modified.year[2] && ! data->voldesc.modified.year[3] + && ! data->voldesc.modified.month[0] && ! data->voldesc.modified.month[1] + && ! data->voldesc.modified.day[0] && ! data->voldesc.modified.day[1] + && ! data->voldesc.modified.hour[0] && ! data->voldesc.modified.hour[1] + && ! data->voldesc.modified.minute[0] && ! data->voldesc.modified.minute[1] + && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1] + && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1]) + { + grub_error (GRUB_ERR_BAD_NUMBER, "No creation date in filesystem to generate UUID."); + *uuid = NULL; + } + else + { + *uuid = grub_malloc (sizeof ("YYYY-MM-DD-HH-mm-ss-hh")); + grub_sprintf (*uuid, "%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + data->voldesc.modified.year[0], data->voldesc.modified.year[1], + data->voldesc.modified.year[2], data->voldesc.modified.year[3], + data->voldesc.modified.month[0], data->voldesc.modified.month[1], + data->voldesc.modified.day[0], data->voldesc.modified.day[1], + data->voldesc.modified.hour[0], data->voldesc.modified.hour[1], + data->voldesc.modified.minute[0], data->voldesc.modified.minute[1], + data->voldesc.modified.second[0], data->voldesc.modified.second[1], + data->voldesc.modified.hundredth[0], data->voldesc.modified.hundredth[1]); + } + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + + + +static struct grub_fs grub_iso9660_fs = + { + .name = "iso9660", + .dir = grub_iso9660_dir, + .open = grub_iso9660_open, + .read = grub_iso9660_read, + .close = grub_iso9660_close, + .label = grub_iso9660_label, + .uuid = grub_iso9660_uuid, + .next = 0 + }; + +GRUB_MOD_INIT(iso9660) +{ + grub_fs_register (&grub_iso9660_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(iso9660) +{ + grub_fs_unregister (&grub_iso9660_fs); +} diff --git a/fs/jfs.c b/fs/jfs.c new file mode 100644 index 0000000..fc9dab8 --- /dev/null +++ b/fs/jfs.c @@ -0,0 +1,885 @@ +/* jfs.c - JFS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_JFS_MAX_SYMLNK_CNT 8 +#define GRUB_JFS_FILETYPE_MASK 0170000 +#define GRUB_JFS_FILETYPE_REG 0100000 +#define GRUB_JFS_FILETYPE_LNK 0120000 +#define GRUB_JFS_FILETYPE_DIR 0040000 + +#define GRUB_JFS_SBLOCK 64 +#define GRUB_JFS_AGGR_INODE 2 +#define GRUB_JFS_FS1_INODE_BLK 104 + +#define GRUB_JFS_TREE_LEAF 2 + +struct grub_jfs_sblock +{ + /* The magic for JFS. It should contain the string "JFS1". */ + grub_uint8_t magic[4]; + grub_uint32_t version; + grub_uint64_t ag_size; + + /* The size of a filesystem block in bytes. XXX: currently only + 4096 was tested. */ + grub_uint32_t blksz; + grub_uint16_t log2_blksz; + + grub_uint8_t unused[71]; + grub_uint8_t volname[11]; +}; + +struct grub_jfs_extent +{ + /* The length of the extent in filesystem blocks. */ + grub_uint16_t length; + grub_uint8_t length2; + + /* The physical offset of the first block on the disk. */ + grub_uint8_t blk1; + grub_uint32_t blk2; +} __attribute__ ((packed)); + +struct grub_jfs_iag +{ + grub_uint8_t unused[3072]; + struct grub_jfs_extent inodes[128]; +} __attribute__ ((packed)); + + +/* The head of the tree used to find extents. */ +struct grub_jfs_treehead +{ + grub_uint64_t next; + grub_uint64_t prev; + + grub_uint8_t flags; + grub_uint8_t unused; + + grub_uint16_t count; + grub_uint16_t max; + grub_uint8_t unused2[10]; +} __attribute__ ((packed)); + +/* A node in the extent tree. */ +struct grub_jfs_tree_extent +{ + grub_uint8_t flags; + grub_uint16_t unused; + + /* The offset is the key used to lookup an extent. */ + grub_uint8_t offset1; + grub_uint32_t offset2; + + struct grub_jfs_extent extent; +} __attribute__ ((packed)); + +/* The tree of directory entries. */ +struct grub_jfs_tree_dir +{ + /* Pointers to the previous and next tree headers of other nodes on + this level. */ + grub_uint64_t nextb; + grub_uint64_t prevb; + + grub_uint8_t flags; + + /* The amount of dirents in this node. */ + grub_uint8_t count; + grub_uint8_t freecnt; + grub_uint8_t freelist; + grub_uint8_t maxslot; + + /* The location of the sorted array of pointers to dirents. */ + grub_uint8_t sindex; + grub_uint8_t unused[10]; +} __attribute__ ((packed)); + +/* An internal node in the dirents tree. */ +struct grub_jfs_internal_dirent +{ + struct grub_jfs_extent ex; + grub_uint8_t next; + grub_uint8_t len; + grub_uint16_t namepart[11]; +} __attribute__ ((packed)); + +/* A leaf node in the dirents tree. */ +struct grub_jfs_leaf_dirent +{ + /* The inode for this dirent. */ + grub_uint32_t inode; + grub_uint8_t next; + + /* The size of the name. */ + grub_uint8_t len; + grub_uint16_t namepart[11]; + grub_uint32_t index; +} __attribute__ ((packed)); + +/* A leaf in the dirents tree. This one is used if the previously + dirent was not big enough to store the name. */ +struct grub_jfs_leaf_next_dirent +{ + grub_uint8_t next; + grub_uint8_t len; + grub_uint16_t namepart[15]; +} __attribute__ ((packed)); + +struct grub_jfs_inode +{ + grub_uint32_t stamp; + grub_uint32_t fileset; + grub_uint32_t inode; + grub_uint8_t unused[12]; + grub_uint64_t size; + grub_uint8_t unused2[20]; + grub_uint32_t mode; + grub_uint8_t unused3[72]; + grub_uint8_t unused4[96]; + + union + { + /* The tree describing the extents of the file. */ + struct __attribute__ ((packed)) + { + struct grub_jfs_treehead tree; + struct grub_jfs_tree_extent extents[16]; + } file; + union + { + /* The tree describing the dirents. */ + struct + { + grub_uint8_t unused[16]; + grub_uint8_t flags; + + /* Amount of dirents in this node. */ + grub_uint8_t count; + grub_uint8_t freecnt; + grub_uint8_t freelist; + grub_uint32_t idotdot; + grub_uint8_t sorted[8]; + } header; + struct grub_jfs_leaf_dirent dirents[8]; + } dir __attribute__ ((packed)); + /* Fast symlink. */ + struct + { + grub_uint8_t unused[32]; + grub_uint8_t path[128]; + } symlink; + } __attribute__ ((packed)); +} __attribute__ ((packed)); + +struct grub_jfs_data +{ + struct grub_jfs_sblock sblock; + grub_disk_t disk; + struct grub_jfs_inode fileset; + struct grub_jfs_inode currinode; + int pos; + int linknest; +} __attribute__ ((packed)); + +struct grub_jfs_diropen +{ + int index; + union + { + struct grub_jfs_tree_dir header; + struct grub_jfs_leaf_dirent dirent[0]; + struct grub_jfs_leaf_next_dirent next_dirent[0]; + char sorted[0]; + } *dirpage __attribute__ ((packed)); + struct grub_jfs_data *data; + struct grub_jfs_inode *inode; + int count; + char *sorted; + struct grub_jfs_leaf_dirent *leaf; + struct grub_jfs_leaf_next_dirent *next_leaf; + + /* The filename and inode of the last read dirent. */ + char name[255]; + grub_uint32_t ino; +} __attribute__ ((packed)); + + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino); + +/* Get the block number for the block BLK in the node INODE in the + mounted filesystem DATA. */ +static int +grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, + unsigned int blk) +{ + auto int getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents); + + int getblk (struct grub_jfs_treehead *treehead, + struct grub_jfs_tree_extent *extents) + { + int found = -1; + int i; + + for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) + { + if (treehead->flags & GRUB_JFS_TREE_LEAF) + { + /* Read the leafnode. */ + if (grub_le_to_cpu32 (extents[i].offset2) <= blk + && ((grub_le_to_cpu16 (extents[i].extent.length)) + + (extents[i].extent.length2 << 8) + + grub_le_to_cpu32 (extents[i].offset2)) > blk) + return (blk - grub_le_to_cpu32 (extents[i].offset2) + + grub_le_to_cpu32 (extents[i].extent.blk2)); + } + else + if (blk >= grub_le_to_cpu32 (extents[i].offset2)) + found = i; + } + + if (found != -1) + { + struct + { + struct grub_jfs_treehead treehead; + struct grub_jfs_tree_extent extents[254]; + } tree; + + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (extents[found].extent.blk2) + << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (tree), (char *) &tree)) + return -1; + + return getblk (&tree.treehead, &tree.extents[0]); + } + + return -1; + } + + return getblk (&inode->file.tree, &inode->file.extents[0]); +} + + +static grub_err_t +grub_jfs_read_inode (struct grub_jfs_data *data, int ino, + struct grub_jfs_inode *inode) +{ + struct grub_jfs_iag iag; + int iagnum = ino / 4096; + int inoext = (ino % 4096) / 32; + int inonum = (ino % 4096) % 32; + grub_uint32_t iagblk; + grub_uint32_t inoblk; + + iagblk = grub_jfs_blkno (data, &data->fileset, iagnum + 1); + if (grub_errno) + return grub_errno; + + /* Read in the IAG. */ + if (grub_disk_read (data->disk, + iagblk << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), 0, + sizeof (struct grub_jfs_iag), (char *) &iag)) + return grub_errno; + + inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2); + inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS); + inoblk += inonum; + + if (grub_disk_read (data->disk, inoblk, 0, + sizeof (struct grub_jfs_inode), (char *) inode)) + return grub_errno; + + return 0; +} + + +static struct grub_jfs_data * +grub_jfs_mount (grub_disk_t disk) +{ + struct grub_jfs_data *data = 0; + + data = grub_malloc (sizeof (struct grub_jfs_data)); + if (!data) + return 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, GRUB_JFS_SBLOCK, 0, + sizeof (struct grub_jfs_sblock), (char *) &data->sblock)) + goto fail; + + if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4)) + { + grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem"); + goto fail; + } + + data->disk = disk; + data->pos = 0; + data->linknest = 0; + + /* Read the inode of the first fileset. */ + if (grub_disk_read (data->disk, GRUB_JFS_FS1_INODE_BLK, 0, + sizeof (struct grub_jfs_inode), (char *) &data->fileset)) + goto fail; + + return data; + + fail: + grub_free (data); + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem"); + + return 0; +} + + +static struct grub_jfs_diropen * +grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) +{ + struct grub_jfs_internal_dirent *de; + struct grub_jfs_diropen *diro; + int blk; + + de = (struct grub_jfs_internal_dirent *) inode->dir.dirents; + + if (!((grub_le_to_cpu32 (inode->mode) + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + return 0; + } + + diro = grub_malloc (sizeof (struct grub_jfs_diropen)); + if (!diro) + return 0; + + diro->index = 0; + diro->data = data; + diro->inode = inode; + + /* Check if the entire tree is contained within the inode. */ + if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF) + { + diro->leaf = inode->dir.dirents; + diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de; + diro->sorted = (char *) (inode->dir.header.sorted); + diro->count = inode->dir.header.count; + diro->dirpage = 0; + + return diro; + } + + diro->dirpage = grub_malloc (grub_le_to_cpu32 (data->sblock.blksz)); + if (!diro->dirpage) + { + grub_free (diro); + return 0; + } + + blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2); + blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); + + /* Read in the nodes until we are on the leaf node level. */ + do + { + int index; + if (grub_disk_read (data->disk, blk, 0, + grub_le_to_cpu32 (data->sblock.blksz), + diro->dirpage->sorted)) + { + grub_free (diro->dirpage); + grub_free (diro); + return 0; + } + + de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent; + index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32]; + blk = (grub_le_to_cpu32 (de[index].ex.blk2) + << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS)); + } while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF)); + + diro->leaf = diro->dirpage->dirent; + diro->next_leaf = diro->dirpage->next_dirent; + diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32]; + diro->count = diro->dirpage->header.count; + + return diro; +} + + +static void +grub_jfs_closedir (struct grub_jfs_diropen *diro) +{ + if (!diro) + return; + grub_free (diro->dirpage); + grub_free (diro); +} + + +/* Read in the next dirent from the directory described by DIRO. */ +static grub_err_t +grub_jfs_getent (struct grub_jfs_diropen *diro) +{ + int strpos = 0; + struct grub_jfs_leaf_dirent *leaf; + struct grub_jfs_leaf_next_dirent *next_leaf; + int len; + int nextent; + grub_uint16_t filename[255]; + + auto void addstr (grub_uint16_t *uname, int ulen); + + /* Add the unicode string to the utf16 filename buffer. */ + void addstr (grub_uint16_t *name, int ulen) + { + while (ulen--) + filename[strpos++] = *(name++); + } + + /* The last node, read in more. */ + if (diro->index == diro->count) + { + unsigned int next; + + /* If the inode contains the entry tree or if this was the last + node, there is nothing to read. */ + if ((diro->inode->file.tree.flags & GRUB_JFS_TREE_LEAF) + || !grub_le_to_cpu64 (diro->dirpage->header.nextb)) + return GRUB_ERR_OUT_OF_RANGE; + + next = grub_le_to_cpu64 (diro->dirpage->header.nextb); + next <<= (grub_le_to_cpu16 (diro->data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS); + + if (grub_disk_read (diro->data->disk, next, 0, + grub_le_to_cpu32 (diro->data->sblock.blksz), + diro->dirpage->sorted)) + return grub_errno; + + diro->leaf = diro->dirpage->dirent; + diro->next_leaf = diro->dirpage->next_dirent; + diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32]; + diro->count = diro->dirpage->header.count; + diro->index = 0; + } + + leaf = &diro->leaf[(int) diro->sorted[diro->index]]; + next_leaf = &diro->next_leaf[diro->index]; + + len = leaf->len; + if (!len) + { + diro->index++; + return grub_jfs_getent (diro); + } + + addstr (leaf->namepart, len < 11 ? len : 11); + diro->ino = grub_le_to_cpu32 (leaf->inode); + len -= 11; + + /* Move down to the leaf level. */ + nextent = leaf->next; + if (leaf->next != 255) + do + { + next_leaf = &diro->next_leaf[nextent]; + addstr (next_leaf->namepart, len < 15 ? len : 15 ); + + len -= 15; + nextent = next_leaf->next; + } while (next_leaf->next != 255 && len > 0); + + diro->index++; + + /* Convert the temporary UTF16 filename to UTF8. */ + *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0'; + + return 0; +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_jfs_read_file (struct grub_jfs_data *data, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + int i; + int blockcnt; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > data->currinode.size) + len = data->currinode.size; + + blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1) + / grub_le_to_cpu32 (data->sblock.blksz)); + + for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++) + { + int blknr; + int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz); + int blockend = grub_le_to_cpu32 (data->sblock.blksz); + + int skipfirst = 0; + + blknr = grub_jfs_blkno (data, &data->currinode, i); + if (grub_errno) + return -1; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz); + + if (!blockend) + blockend = grub_le_to_cpu32 (data->sblock.blksz); + } + + /* First block. */ + if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz))) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + data->disk->read_hook = read_hook; + grub_disk_read (data->disk, + blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), + skipfirst, blockend, buf); + + data->disk->read_hook = 0; + if (grub_errno) + return -1; + + buf += grub_le_to_cpu32 (data->sblock.blksz) - skipfirst; + } + + return len; +} + + +/* Find the file with the pathname PATH on the filesystem described by + DATA. */ +static grub_err_t +grub_jfs_find_file (struct grub_jfs_data *data, const char *path) +{ + char fpath[grub_strlen (path)]; + char *name = fpath; + char *next; + unsigned int pos = 0; + struct grub_jfs_diropen *diro; + + grub_strncpy (fpath, path, grub_strlen (path) + 1); + + if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode)) + return grub_errno; + + /* Skip the first slashes. */ + while (*name == '/') + { + name++; + if (!*name) + return 0; + } + + /* Extract the actual part from the pathname. */ + next = grub_strchr (name, '/'); + if (next) + { + while (*next == '/') + { + next[0] = '\0'; + next++; + } + } + diro = grub_jfs_opendir (data, &data->currinode); + if (!diro) + return grub_errno; + + for (;;) + { + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; + + if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE) + break; + + /* Check if the current direntry matches the current part of the + pathname. */ + if (!grub_strcmp (name, diro->name)) + { + int ino = diro->ino; + int dirino = grub_le_to_cpu32 (data->currinode.inode); + + grub_jfs_closedir (diro); + diro = 0; + + if (grub_jfs_read_inode (data, ino, &data->currinode)) + break; + + /* Check if this is a symlink. */ + if ((grub_le_to_cpu32 (data->currinode.mode) + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK) + { + grub_jfs_lookup_symlink (data, dirino); + if (grub_errno) + return grub_errno; + } + + if (!next) + return 0; + + pos = 0; + + name = next; + next = grub_strchr (name, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + /* Open this directory for reading dirents. */ + diro = grub_jfs_opendir (data, &data->currinode); + if (!diro) + return grub_errno; + + continue; + } + } + + grub_jfs_closedir (diro); + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_errno; +} + + +static grub_err_t +grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino) +{ + int size = grub_le_to_cpu64 (data->currinode.size); + char symlink[size + 1]; + + if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT) + return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); + + if (size <= 128) + grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128); + else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0) + return grub_errno; + + symlink[size] = '\0'; + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + ino = 2; + + /* Now load in the old inode. */ + if (grub_jfs_read_inode (data, ino, &data->currinode)) + return grub_errno; + + grub_jfs_find_file (data, symlink); + if (grub_errno) + grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + + return grub_errno; +} + + +static grub_err_t +grub_jfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_jfs_data *data = 0; + struct grub_jfs_diropen *diro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_jfs_mount (device->disk); + if (!data) + goto fail; + + if (grub_jfs_find_file (data, path)) + goto fail; + + diro = grub_jfs_opendir (data, &data->currinode); + if (!diro) + goto fail; + + /* Iterate over the dirents in the directory that was found. */ + while (grub_jfs_getent (diro) != GRUB_ERR_OUT_OF_RANGE) + { + struct grub_jfs_inode inode; + int isdir; + + if (grub_jfs_read_inode (data, diro->ino, &inode)) + goto fail; + + isdir = (grub_le_to_cpu32 (inode.mode) + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; + if (hook (diro->name, isdir)) + goto fail; + } + + /* XXX: GRUB_ERR_OUT_OF_RANGE is used for the last dirent. */ + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_errno = 0; + + fail: + grub_jfs_closedir (diro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_jfs_open (struct grub_file *file, const char *name) +{ + struct grub_jfs_data *data; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_jfs_mount (file->device->disk); + if (!data) + goto fail; + + grub_jfs_find_file (data, name); + if (grub_errno) + goto fail; + + /* It is only possible for open regular files. */ + if (! ((grub_le_to_cpu32 (data->currinode.mode) + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file"); + goto fail; + } + + file->data = data; + file->size = grub_le_to_cpu64 (data->currinode.size); + + return 0; + + fail: + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno;; +} + + +static grub_ssize_t +grub_jfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_jfs_data *data = + (struct grub_jfs_data *) file->data; + + return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf); +} + + +static grub_err_t +grub_jfs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_jfs_label (grub_device_t device, char **label) +{ + struct grub_jfs_data *data; + data = grub_jfs_mount (device->disk); + + if (data) + *label = grub_strndup ((char *) (data->sblock.volname), 11); + else + *label = 0; + + return grub_errno; +} + + +static struct grub_fs grub_jfs_fs = + { + .name = "jfs", + .dir = grub_jfs_dir, + .open = grub_jfs_open, + .read = grub_jfs_read, + .close = grub_jfs_close, + .label = grub_jfs_label, + .next = 0 + }; + +GRUB_MOD_INIT(jfs) +{ + grub_fs_register (&grub_jfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(jfs) +{ + grub_fs_unregister (&grub_jfs_fs); +} diff --git a/fs/minix.c b/fs/minix.c new file mode 100644 index 0000000..cc03d7d --- /dev/null +++ b/fs/minix.c @@ -0,0 +1,613 @@ +/* minix.c - The minix filesystem, version 1 and 2. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_MINIX_MAGIC 0x137F +#define GRUB_MINIX2_MAGIC 0x2468 +#define GRUB_MINIX_MAGIC_30 0x138F +#define GRUB_MINIX2_MAGIC_30 0x2478 +#define GRUB_MINIX_BSIZE 1024U +#define GRUB_MINIX_LOG2_BSIZE 1 +#define GRUB_MINIX_ROOT_INODE 1 +#define GRUB_MINIX_MAX_SYMLNK_CNT 8 +#define GRUB_MINIX_SBLOCK 2 + +#define GRUB_MINIX_IFDIR 0040000U +#define GRUB_MINIX_IFLNK 0120000U + +#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \ + data->inode. field : data->inode2. field) +#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ? \ + grub_le_to_cpu##bits1 (data->inode.field) : \ + grub_le_to_cpu##bits2 (data->inode2.field)) +#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32) +#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16) +#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN \ + (data,dir_zones[blk],16,32) +#define GRUB_MINIX_INODE_INDIR_ZONE(data) \ + GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32) +#define GRUB_MINIX_INODE_DINDIR_ZONE(data) \ + GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32) +#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4) +#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \ + + grub_le_to_cpu16 (sblock->log2_zone_size)) +#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \ + << grub_le_to_cpu16 (sblock->log2_zone_size)) + +struct grub_minix_sblock +{ + grub_uint16_t inode_cnt; + grub_uint16_t zone_cnt; + grub_uint16_t inode_bmap_size; + grub_uint16_t zone_bmap_size; + grub_uint16_t first_data_zone; + grub_uint16_t log2_zone_size; + grub_uint32_t max_file_size; + grub_uint16_t magic; +}; + +struct grub_minix_inode +{ + grub_uint16_t mode; + grub_uint16_t uid; + grub_uint16_t size; + grub_uint32_t ctime; + grub_uint8_t gid; + grub_uint8_t nlinks; + grub_uint16_t dir_zones[7]; + grub_uint16_t indir_zone; + grub_uint16_t double_indir_zone; +}; + +struct grub_minix2_inode +{ + grub_uint16_t mode; + grub_uint16_t nlinks; + grub_uint16_t uid; + grub_uint16_t gid; + grub_uint32_t size; + grub_uint32_t atime; + grub_uint32_t mtime; + grub_uint32_t ctime; + grub_uint32_t dir_zones[7]; + grub_uint32_t indir_zone; + grub_uint32_t double_indir_zone; + grub_uint32_t unused; + +}; + +/* Information about a "mounted" minix filesystem. */ +struct grub_minix_data +{ + struct grub_minix_sblock sblock; + struct grub_minix_inode inode; + struct grub_minix2_inode inode2; + int ino; + int linknest; + grub_disk_t disk; + int version; + int filename_size; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static grub_err_t grub_minix_find_file (struct grub_minix_data *data, + const char *path); + +static int +grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) +{ + struct grub_minix_sblock *sblock = &data->sblock; + int indir; + + auto int grub_get_indir (int, int); + + /* Read the block pointer in ZONE, on the offset NUM. */ + int grub_get_indir (int zone, int num) + { + if (data->version == 1) + { + grub_uint16_t indir16; + grub_disk_read (data->disk, + zone << GRUB_MINIX_LOG2_ZONESZ, + sizeof (grub_uint16_t) * num, + sizeof (grub_uint16_t), (char *) &indir16); + return grub_le_to_cpu16 (indir16); + } + else + { + grub_uint32_t indir32; + grub_disk_read (data->disk, + zone << GRUB_MINIX_LOG2_ZONESZ, + sizeof (grub_uint32_t) * num, + sizeof (grub_uint32_t), (char *) &indir32); + return grub_le_to_cpu32 (indir32); + } + } + + /* Direct block. */ + if (blk < 7) + return GRUB_MINIX_INODE_DIR_ZONES (data, blk); + + /* Indirect block. */ + blk -= 7; + if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) + { + indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk); + return indir; + } + + /* Double indirect block. */ + blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data); + if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)) + * (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))) + { + indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data), + blk / GRUB_MINIX_ZONESZ); + + indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ); + + return indir; + } + + /* This should never happen. */ + grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size"); + + return 0; +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_minix_read_file (struct grub_minix_data *data, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_disk_addr_t len, char *buf) +{ + struct grub_minix_sblock *sblock = &data->sblock; + int i; + int blockcnt; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > GRUB_MINIX_INODE_SIZE (data)) + len = GRUB_MINIX_INODE_SIZE (data); + + blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE; + + for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++) + { + int blknr; + int blockoff = pos % GRUB_MINIX_BSIZE; + int blockend = GRUB_MINIX_BSIZE; + + int skipfirst = 0; + + blknr = grub_minix_get_file_block (data, i); + if (grub_errno) + return -1; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) % GRUB_MINIX_BSIZE; + + if (!blockend) + blockend = GRUB_MINIX_BSIZE; + } + + /* First block. */ + if (i == (pos / (int) GRUB_MINIX_BSIZE)) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + data->disk->read_hook = read_hook; + grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ, + skipfirst, blockend, buf); + + data->disk->read_hook = 0; + if (grub_errno) + return -1; + + buf += GRUB_MINIX_BSIZE - skipfirst; + } + + return len; +} + + +/* Read inode INO from the mounted filesystem described by DATA. This + inode is used by default now. */ +static grub_err_t +grub_minix_read_inode (struct grub_minix_data *data, int ino) +{ + struct grub_minix_sblock *sblock = &data->sblock; + + /* Block in which the inode is stored. */ + int block; + data->ino = ino; + + /* The first inode in minix is inode 1. */ + ino--; + + block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size) + + grub_le_to_cpu16 (sblock->zone_bmap_size)) + << GRUB_MINIX_LOG2_BSIZE); + + if (data->version == 1) + { + block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode)); + int offs = (ino % (GRUB_DISK_SECTOR_SIZE + / sizeof (struct grub_minix_inode)) + * sizeof (struct grub_minix_inode)); + + grub_disk_read (data->disk, block, offs, + sizeof (struct grub_minix_inode), (char *) &data->inode); + } + else + { + block += ino / (GRUB_DISK_SECTOR_SIZE + / sizeof (struct grub_minix2_inode)); + int offs = (ino + % (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode)) + * sizeof (struct grub_minix2_inode)); + + grub_disk_read (data->disk, block, offs, + sizeof (struct grub_minix2_inode),(char *) &data->inode2); + } + + return GRUB_ERR_NONE; +} + + +/* Lookup the symlink the current inode points to. INO is the inode + number of the directory the symlink is relative to. */ +static grub_err_t +grub_minix_lookup_symlink (struct grub_minix_data *data, int ino) +{ + char symlink[GRUB_MINIX_INODE_SIZE (data) + 1]; + + if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT) + return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); + + if (grub_minix_read_file (data, 0, 0, + GRUB_MINIX_INODE_SIZE (data), symlink) < 0) + return grub_errno; + + symlink[GRUB_MINIX_INODE_SIZE (data)] = '\0'; + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + ino = GRUB_MINIX_ROOT_INODE; + + /* Now load in the old inode. */ + if (grub_minix_read_inode (data, ino)) + return grub_errno; + + grub_minix_find_file (data, symlink); + if (grub_errno) + grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + + return grub_errno; +} + + +/* Find the file with the pathname PATH on the filesystem described by + DATA. */ +static grub_err_t +grub_minix_find_file (struct grub_minix_data *data, const char *path) +{ + char fpath[grub_strlen (path) + 1]; + char *name = fpath; + char *next; + unsigned int pos = 0; + int dirino; + + grub_strcpy (fpath, path); + + /* Skip the first slash. */ + if (name[0] == '/') + { + name++; + if (!*name) + return 0; + } + + /* Extract the actual part from the pathname. */ + next = grub_strchr (name, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + do + { + grub_uint16_t ino; + char filename[data->filename_size + 1]; + + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; + + if (grub_minix_read_file (data, 0, pos, sizeof (ino), + (char *) &ino) < 0) + return grub_errno; + if (grub_minix_read_file (data, 0, pos + sizeof (ino), + data->filename_size, (char *) filename)< 0) + return grub_errno; + + filename[data->filename_size] = '\0'; + + /* Check if the current direntry matches the current part of the + pathname. */ + if (!grub_strcmp (name, filename)) + { + dirino = data->ino; + grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); + + /* Follow the symlink. */ + if ((GRUB_MINIX_INODE_MODE (data) + & GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK) + { + grub_minix_lookup_symlink (data, dirino); + if (grub_errno) + return grub_errno; + } + + if (!next) + return 0; + + pos = 0; + + name = next; + next = grub_strchr (name, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + if ((GRUB_MINIX_INODE_MODE (data) + & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + continue; + } + + pos += sizeof (ino) + data->filename_size; + } while (pos < GRUB_MINIX_INODE_SIZE (data)); + + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_errno; +} + + +/* Mount the filesystem on the disk DISK. */ +static struct grub_minix_data * +grub_minix_mount (grub_disk_t disk) +{ + struct grub_minix_data *data; + + data = grub_malloc (sizeof (struct grub_minix_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, GRUB_MINIX_SBLOCK, 0, + sizeof (struct grub_minix_sblock),(char *) &data->sblock); + if (grub_errno) + goto fail; + + if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC) + { + data->version = 1; + data->filename_size = 14; + } + else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC) + { + data->version = 2; + data->filename_size = 14; + } + else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30) + { + data->version = 1; + data->filename_size = 30; + } + else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30) + { + data->version = 2; + data->filename_size = 30; + } + else + goto fail; + + data->disk = disk; + data->linknest = 0; + + return data; + + fail: + grub_free (data); + grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem"); + return 0; +} + +static grub_err_t +grub_minix_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_minix_data *data = 0; + struct grub_minix_sblock *sblock; + unsigned int pos = 0; + + data = grub_minix_mount (device->disk); + if (!data) + return grub_errno; + + grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE); + if (grub_errno) + goto fail; + + sblock = &data->sblock; + + grub_minix_find_file (data, path); + if (grub_errno) + goto fail; + + if ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + goto fail; + } + + while (pos < GRUB_MINIX_INODE_SIZE (data)) + { + grub_uint16_t ino; + char filename[data->filename_size + 1]; + int dirino = data->ino; + + if (grub_minix_read_file (data, 0, pos, sizeof (ino), + (char *) &ino) < 0) + return grub_errno; + + if (grub_minix_read_file (data, 0, pos + sizeof (ino), + data->filename_size, + (char *) filename) < 0) + return grub_errno; + filename[data->filename_size] = '\0'; + + /* The filetype is not stored in the dirent. Read the inode to + find out the filetype. This *REALLY* sucks. */ + grub_minix_read_inode (data, grub_le_to_cpu16 (ino)); + if (hook (filename, ((GRUB_MINIX_INODE_MODE (data) + & GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR)) ? 1 : 0) + break; + + /* Load the old inode back in. */ + grub_minix_read_inode (data, dirino); + + pos += sizeof (ino) + data->filename_size; + } + + fail: + grub_free (data); + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_minix_open (struct grub_file *file, const char *name) +{ + struct grub_minix_data *data; + data = grub_minix_mount (file->device->disk); + if (!data) + return grub_errno; + + /* Open the inode op the root directory. */ + grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE); + if (grub_errno) + { + grub_free (data); + return grub_errno; + } + + if (!name || name[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return grub_errno; + } + + /* Traverse the directory tree to the node that should be + opened. */ + grub_minix_find_file (data, name); + if (grub_errno) + { + grub_free (data); + return grub_errno; + } + + file->data = data; + file->size = GRUB_MINIX_INODE_SIZE (data); + + return GRUB_ERR_NONE; +} + + +static grub_ssize_t +grub_minix_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_minix_data *data = + (struct grub_minix_data *) file->data; + + return grub_minix_read_file (data, file->read_hook, file->offset, len, buf); +} + + +static grub_err_t +grub_minix_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_minix_label (grub_device_t device __attribute ((unused)), + char **label __attribute ((unused))) +{ + return GRUB_ERR_NONE; +} + + +static struct grub_fs grub_minix_fs = + { + .name = "minix", + .dir = grub_minix_dir, + .open = grub_minix_open, + .read = grub_minix_read, + .close = grub_minix_close, + .label = grub_minix_label, + .next = 0 + }; + +GRUB_MOD_INIT(minix) +{ + grub_fs_register (&grub_minix_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(minix) +{ + grub_fs_unregister (&grub_minix_fs); +} diff --git a/fs/ntfs.c b/fs/ntfs.c new file mode 100644 index 0000000..22477c5 --- /dev/null +++ b/fs/ntfs.c @@ -0,0 +1,1141 @@ +/* ntfs.c - NTFS filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +ntfscomp_func_t grub_ntfscomp_func; + +static grub_err_t +fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) +{ + int ss; + char *pu; + grub_uint16_t us; + + if (grub_memcmp (buf, magic, 4)) + return grub_error (GRUB_ERR_BAD_FS, "%s label not found", magic); + + ss = u16at (buf, 6) - 1; + if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE) + return grub_error (GRUB_ERR_BAD_FS, "Size not match", + ss * (int) data->blocksize, + len * GRUB_DISK_SECTOR_SIZE); + pu = buf + u16at (buf, 4); + us = u16at (pu, 0); + buf -= 2; + while (ss > 0) + { + buf += data->blocksize; + pu += 2; + if (u16at (buf, 0) != us) + return grub_error (GRUB_ERR_BAD_FS, "Fixup signature not match"); + v16at (buf, 0) = v16at (pu, 0); + ss--; + } + + return 0; +} + +static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, + grub_uint32_t mftno); +static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, + grub_uint32_t ofs, grub_uint32_t len, + int cached, + void + NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t + sector, + unsigned offset, + unsigned length)); + +static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + grub_uint32_t ofs, grub_uint32_t len, + int cached, + void + NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t + sector, + unsigned offset, + unsigned length)); + +static void +init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) +{ + at->mft = mft; + at->flags = (mft == &mft->data->mmft) ? AF_MMFT : 0; + at->attr_nxt = mft->buf + u16at (mft->buf, 0x14); + at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; +} + +static void +free_attr (struct grub_ntfs_attr *at) +{ + grub_free (at->emft_buf); + grub_free (at->edat_buf); + grub_free (at->sbuf); +} + +static char * +find_attr (struct grub_ntfs_attr *at, unsigned char attr) +{ + if (at->flags & AF_ALST) + { + retry: + while (at->attr_nxt < at->attr_end) + { + at->attr_cur = at->attr_nxt; + at->attr_nxt += u16at (at->attr_cur, 4); + if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) + { + char *new_pos; + + if (at->flags & AF_MMFT) + { + if ((grub_disk_read + (at->mft->data->disk, v32at (at->attr_cur, 0x10), 0, + 512, at->emft_buf)) + || + (grub_disk_read + (at->mft->data->disk, v32at (at->attr_cur, 0x14), 0, + 512, at->emft_buf + 512))) + return NULL; + + if (fixup + (at->mft->data, at->emft_buf, at->mft->data->mft_size, + "FILE")) + return NULL; + } + else + { + if (read_mft (at->mft->data, at->emft_buf, + u32at (at->attr_cur, 0x10))) + return NULL; + } + + new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)]; + while ((unsigned char) *new_pos != 0xFF) + { + if (((unsigned char) *new_pos == + (unsigned char) *at->attr_cur) + && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) + { + return new_pos; + } + new_pos += u16at (new_pos, 4); + } + grub_error (GRUB_ERR_BAD_FS, + "Can\'t find 0x%X in attribute list", + (unsigned char) *at->attr_cur); + return NULL; + } + } + return NULL; + } + at->attr_cur = at->attr_nxt; + while ((unsigned char) *at->attr_cur != 0xFF) + { + at->attr_nxt += u16at (at->attr_cur, 4); + if ((unsigned char) *at->attr_cur == AT_ATTRIBUTE_LIST) + at->attr_end = at->attr_cur; + if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) + return at->attr_cur; + at->attr_cur = at->attr_nxt; + } + if (at->attr_end) + { + char *pa; + + at->emft_buf = grub_malloc (at->mft->data->mft_size << BLK_SHR); + if (at->emft_buf == NULL) + return NULL; + + pa = at->attr_end; + if (pa[8]) + { + int n; + + n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1) + & (~(GRUB_DISK_SECTOR_SIZE - 1))); + at->attr_cur = at->attr_end; + at->edat_buf = grub_malloc (n); + if (!at->edat_buf) + return NULL; + if (read_data (at, pa, at->edat_buf, 0, n, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "Fail to read non-resident attribute list"); + return NULL; + } + at->attr_nxt = at->edat_buf; + at->attr_end = at->edat_buf + u32at (pa, 0x30); + } + else + { + at->attr_nxt = at->attr_end + u16at (pa, 0x14); + at->attr_end = at->attr_end + u32at (pa, 4); + } + at->flags |= AF_ALST; + while (at->attr_nxt < at->attr_end) + { + if (((unsigned char) *at->attr_nxt == attr) || (attr == 0)) + break; + at->attr_nxt += u16at (at->attr_nxt, 4); + } + if (at->attr_nxt >= at->attr_end) + return NULL; + + if ((at->flags & AF_MMFT) && (attr == AT_DATA)) + { + at->flags |= AF_GPOS; + at->attr_cur = at->attr_nxt; + pa = at->attr_cur; + v32at (pa, 0x10) = at->mft->data->mft_start; + v32at (pa, 0x14) = at->mft->data->mft_start + 1; + pa = at->attr_nxt + u16at (pa, 4); + while (pa < at->attr_end) + { + if ((unsigned char) *pa != attr) + break; + if (read_attr + (at, pa + 0x10, + u32at (pa, 0x10) * (at->mft->data->mft_size << BLK_SHR), + at->mft->data->mft_size << BLK_SHR, 0, 0)) + return NULL; + pa += u16at (pa, 4); + } + at->attr_nxt = at->attr_cur; + at->flags &= ~AF_GPOS; + } + goto retry; + } + return NULL; +} + +static char * +locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, + unsigned char attr) +{ + char *pa; + + init_attr (at, mft); + if ((pa = find_attr (at, attr)) == NULL) + return NULL; + if ((at->flags & AF_ALST) == 0) + { + while (1) + { + if ((pa = find_attr (at, attr)) == NULL) + break; + if (at->flags & AF_ALST) + return pa; + } + grub_errno = GRUB_ERR_NONE; + free_attr (at); + init_attr (at, mft); + pa = find_attr (at, attr); + } + return pa; +} + +static char * +read_run_data (char *run, int nn, grub_uint32_t * val, int sig) +{ + grub_uint32_t r, v; + + r = 0; + v = 1; + + while (nn--) + { + r += v * (*(unsigned char *) (run++)); + v <<= 8; + } + + if ((sig) && (r & (v >> 1))) + r -= v; + + *val = r; + return run; +} + +grub_err_t +grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx) +{ + int c1, c2; + grub_uint32_t val; + char *run; + + run = ctx->cur_run; +retry: + c1 = ((unsigned char) (*run) & 0xF); + c2 = ((unsigned char) (*run) >> 4); + if (!c1) + { + if ((ctx->attr) && (ctx->attr->flags & AF_ALST)) + { + void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length); + + save_hook = ctx->comp.disk->read_hook; + ctx->comp.disk->read_hook = 0; + run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur); + ctx->comp.disk->read_hook = save_hook; + if (run) + { + if (run[8] == 0) + return grub_error (GRUB_ERR_BAD_FS, + "$DATA should be non-resident"); + + run += u16at (run, 0x20); + ctx->curr_lcn = 0; + goto retry; + } + } + return grub_error (GRUB_ERR_BAD_FS, "Run list overflown"); + } + run = read_run_data (run + 1, c1, &val, 0); /* length of current VCN */ + ctx->curr_vcn = ctx->next_vcn; + ctx->next_vcn += val; + run = read_run_data (run, c2, &val, 1); /* offset to previous LCN */ + ctx->curr_lcn += val; + if (val == 0) + ctx->flags |= RF_BLNK; + else + ctx->flags &= ~RF_BLNK; + ctx->cur_run = run; + return 0; +} + +static grub_disk_addr_t +grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) +{ + struct grub_ntfs_rlst *ctx; + + ctx = (struct grub_ntfs_rlst *) node; + if ((grub_uint32_t) block >= ctx->next_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return -1; + return ctx->curr_lcn; + } + else + return (ctx->flags & RF_BLNK) ? 0 : ((grub_uint32_t) block - + ctx->curr_vcn + ctx->curr_lcn); +} + +static grub_err_t +read_data (struct grub_ntfs_attr *at, char *pa, char *dest, grub_uint32_t ofs, + grub_uint32_t len, int cached, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length)) +{ + grub_uint32_t vcn; + struct grub_ntfs_rlst cc, *ctx; + + if (len == 0) + return 0; + + grub_memset (&cc, 0, sizeof (cc)); + ctx = &cc; + ctx->attr = at; + ctx->comp.spc = at->mft->data->spc; + ctx->comp.disk = at->mft->data->disk; + + if (pa[8] == 0) + { + if (ofs + len > u32at (pa, 0x10)) + return grub_error (GRUB_ERR_BAD_FS, "Read out of range"); + grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); + return 0; + } + + if (u16at (pa, 0xC) & FLAG_COMPRESSED) + ctx->flags |= RF_COMP; + else + ctx->flags &= ~RF_COMP; + ctx->cur_run = pa + u16at (pa, 0x20); + + if (ctx->flags & RF_COMP) + { + if (!cached) + return grub_error (GRUB_ERR_BAD_FS, "Attribute can\'t be compressed"); + + if (at->sbuf) + { + if ((ofs & (~(COM_LEN - 1))) == at->save_pos) + { + grub_uint32_t n; + + n = COM_LEN - (ofs - at->save_pos); + if (n > len) + n = len; + + grub_memcpy (dest, at->sbuf + ofs - at->save_pos, n); + if (n == len) + return 0; + + dest += n; + len -= n; + ofs += n; + } + } + else + { + at->sbuf = grub_malloc (COM_LEN); + if (at->sbuf == NULL) + return grub_errno; + at->save_pos = 1; + } + + vcn = ctx->target_vcn = (ofs / COM_LEN) * (COM_SEC / ctx->comp.spc); + ctx->target_vcn &= ~0xF; + } + else + vcn = ctx->target_vcn = (ofs >> BLK_SHR) / ctx->comp.spc; + + ctx->next_vcn = u32at (pa, 0x10); + ctx->curr_lcn = 0; + while (ctx->next_vcn <= ctx->target_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + } + + if (at->flags & AF_GPOS) + { + grub_uint32_t st0, st1; + + st0 = + (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + + ((ofs >> BLK_SHR) % ctx->comp.spc); + st1 = st0 + 1; + if (st1 == + (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + st1 = ctx->curr_lcn * ctx->comp.spc; + } + v32at (dest, 0) = st0; + v32at (dest, 4) = st1; + return 0; + } + + if (!(ctx->flags & RF_COMP)) + { + unsigned int pow; + + if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow)) + grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, + read_hook, ofs, len, dest, + grub_ntfs_read_block, ofs + len, pow); + return grub_errno; + } + + return (grub_ntfscomp_func) ? grub_ntfscomp_func (at, dest, ofs, len, ctx, + vcn) : + grub_error (GRUB_ERR_BAD_FS, "ntfscomp module not loaded"); +} + +static grub_err_t +read_attr (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, + grub_uint32_t len, int cached, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length)) +{ + char *save_cur; + unsigned char attr; + char *pp; + grub_err_t ret; + + save_cur = at->attr_cur; + at->attr_nxt = at->attr_cur; + attr = (unsigned char) *at->attr_nxt; + if (at->flags & AF_ALST) + { + char *pa; + grub_uint32_t vcn; + + vcn = ofs / (at->mft->data->spc << BLK_SHR); + pa = at->attr_nxt + u16at (at->attr_nxt, 4); + while (pa < at->attr_end) + { + if ((unsigned char) *pa != attr) + break; + if (u32at (pa, 8) > vcn) + break; + at->attr_nxt = pa; + pa += u16at (pa, 4); + } + } + pp = find_attr (at, attr); + if (pp) + ret = read_data (at, pp, dest, ofs, len, cached, read_hook); + else + ret = + (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, + "Attribute not found"); + at->attr_cur = save_cur; + return ret; +} + +static grub_err_t +read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) +{ + if (read_attr + (&data->mmft.attr, buf, mftno * (data->mft_size << BLK_SHR), + data->mft_size << BLK_SHR, 0, 0)) + return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno); + return fixup (data, buf, data->mft_size, "FILE"); +} + +static grub_err_t +init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) +{ + unsigned short flag; + + mft->inode_read = 1; + + mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + if (mft->buf == NULL) + return grub_errno; + + if (read_mft (mft->data, mft->buf, mftno)) + return grub_errno; + + flag = u16at (mft->buf, 0x16); + if ((flag & 1) == 0) + return grub_error (GRUB_ERR_BAD_FS, "MFT 0x%X is not in use", mftno); + + if ((flag & 2) == 0) + { + char *pa; + + pa = locate_attr (&mft->attr, mft, AT_DATA); + if (pa == NULL) + return grub_error (GRUB_ERR_BAD_FS, "No $DATA in MFT 0x%X", mftno); + + if (!pa[8]) + mft->size = u32at (pa, 0x10); + else + mft->size = u32at (pa, 0x30); + + if ((mft->attr.flags & AF_ALST) == 0) + mft->attr.attr_end = 0; /* Don't jump to attribute list */ + } + else + init_attr (&mft->attr, mft); + + return 0; +} + +static void +free_file (struct grub_ntfs_file *mft) +{ + free_attr (&mft->attr); + grub_free (mft->buf); +} + +static int +list_file (struct grub_ntfs_file *diro, char *pos, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + char *np; + int ns; + + while (1) + { + char *ustr, namespace; + + if (pos[0xC] & 2) /* end signature */ + break; + + np = pos + 0x50; + ns = (unsigned char) *(np++); + namespace = *(np++); + + /* + * Ignore files in DOS namespace, as they will reappear as Win32 + * names. + */ + if ((ns) && (namespace != 2)) + { + enum grub_fshelp_filetype type; + struct grub_ntfs_file *fdiro; + + if (u16at (pos, 4)) + { + grub_error (GRUB_ERR_BAD_FS, "64-bit MFT number"); + return 0; + } + + type = + (u32at (pos, 0x48) & ATTR_DIRECTORY) ? GRUB_FSHELP_DIR : + GRUB_FSHELP_REG; + + fdiro = grub_malloc (sizeof (struct grub_ntfs_file)); + if (!fdiro) + return 0; + + grub_memset (fdiro, 0, sizeof (*fdiro)); + fdiro->data = diro->data; + fdiro->ino = u32at (pos, 0); + + ustr = grub_malloc (ns * 4 + 1); + if (ustr == NULL) + return 0; + *grub_utf16_to_utf8 ((grub_uint8_t *) ustr, (grub_uint16_t *) np, + ns) = '\0'; + + if (namespace) + type |= GRUB_FSHELP_CASE_INSENSITIVE; + + if (hook (ustr, type, fdiro)) + { + grub_free (ustr); + return 1; + } + + grub_free (ustr); + } + pos += u16at (pos, 8); + } + return 0; +} + +static int +grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + unsigned char *bitmap; + struct grub_ntfs_attr attr, *at; + char *cur_pos, *indx, *bmp; + int bitmap_len, ret = 0; + struct grub_ntfs_file *mft; + + mft = (struct grub_ntfs_file *) dir; + + if (!mft->inode_read) + { + if (init_file (mft, mft->ino)) + return 0; + } + + indx = NULL; + bmp = NULL; + + at = &attr; + init_attr (at, mft); + while (1) + { + if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL) + { + grub_error (GRUB_ERR_BAD_FS, "No $INDEX_ROOT"); + goto done; + } + + /* Resident, Namelen=4, Offset=0x18, Flags=0x00, Name="$I30" */ + if ((u32at (cur_pos, 8) != 0x180400) || + (u32at (cur_pos, 0x18) != 0x490024) || + (u32at (cur_pos, 0x1C) != 0x300033)) + continue; + cur_pos += u16at (cur_pos, 0x14); + if (*cur_pos != 0x30) /* Not filename index */ + continue; + break; + } + + cur_pos += 0x10; /* Skip index root */ + ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook); + if (ret) + goto done; + + bitmap = NULL; + bitmap_len = 0; + free_attr (at); + init_attr (at, mft); + while ((cur_pos = find_attr (at, AT_BITMAP)) != NULL) + { + int ofs; + + ofs = (unsigned char) cur_pos[0xA]; + /* Namelen=4, Name="$I30" */ + if ((cur_pos[9] == 4) && + (u32at (cur_pos, ofs) == 0x490024) && + (u32at (cur_pos, ofs + 4) == 0x300033)) + { + int is_resident = (cur_pos[8] == 0); + + bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) : + u32at (cur_pos, 0x28)); + + bmp = grub_malloc (bitmap_len); + if (bmp == NULL) + goto done; + + if (is_resident) + { + grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)), + bitmap_len); + } + else + { + if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "Fails to read non-resident $BITMAP"); + goto done; + } + bitmap_len = u32at (cur_pos, 0x30); + } + + bitmap = (unsigned char *) bmp; + break; + } + } + + free_attr (at); + cur_pos = locate_attr (at, mft, AT_INDEX_ALLOCATION); + while (cur_pos != NULL) + { + /* Non-resident, Namelen=4, Offset=0x40, Flags=0, Name="$I30" */ + if ((u32at (cur_pos, 8) == 0x400401) && + (u32at (cur_pos, 0x40) == 0x490024) && + (u32at (cur_pos, 0x44) == 0x300033)) + break; + cur_pos = find_attr (at, AT_INDEX_ALLOCATION); + } + + if ((!cur_pos) && (bitmap)) + { + grub_error (GRUB_ERR_BAD_FS, "$BITMAP without $INDEX_ALLOCATION"); + goto done; + } + + if (bitmap) + { + grub_uint32_t v, i; + + indx = grub_malloc (mft->data->idx_size << BLK_SHR); + if (indx == NULL) + goto done; + + v = 1; + for (i = 0; i < (grub_uint32_t) bitmap_len * 8; i++) + { + if (*bitmap & v) + { + if ((read_attr + (at, indx, i * (mft->data->idx_size << BLK_SHR), + (mft->data->idx_size << BLK_SHR), 0, 0)) + || (fixup (mft->data, indx, mft->data->idx_size, "INDX"))) + goto done; + ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook); + if (ret) + goto done; + } + v <<= 1; + if (v >= 0x100) + { + v = 1; + bitmap++; + } + } + } + +done: + free_attr (at); + grub_free (indx); + grub_free (bmp); + + return ret; +} + +static struct grub_ntfs_data * +grub_ntfs_mount (grub_disk_t disk) +{ + struct grub_ntfs_bpb bpb; + struct grub_ntfs_data *data = 0; + + if (!disk) + goto fail; + + data = (struct grub_ntfs_data *) grub_malloc (sizeof (*data)); + if (!data) + goto fail; + + grub_memset (data, 0, sizeof (*data)); + + data->disk = disk; + + /* Read the BPB. */ + if (grub_disk_read (disk, 0, 0, sizeof (bpb), (char *) &bpb)) + goto fail; + + if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4)) + goto fail; + + data->blocksize = grub_le_to_cpu16 (bpb.bytes_per_sector); + data->spc = bpb.sectors_per_cluster * (data->blocksize >> BLK_SHR); + + if (bpb.clusters_per_mft > 0) + data->mft_size = data->spc * bpb.clusters_per_mft; + else + data->mft_size = 1 << (-bpb.clusters_per_mft - BLK_SHR); + + if (bpb.clusters_per_index > 0) + data->idx_size = data->spc * bpb.clusters_per_index; + else + data->idx_size = 1 << (-bpb.clusters_per_index - BLK_SHR); + + data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc; + + if ((data->mft_size > MAX_MFT) || (data->idx_size > MAX_IDX)) + goto fail; + + data->mmft.data = data; + data->cmft.data = data; + + data->mmft.buf = grub_malloc (data->mft_size << BLK_SHR); + if (!data->mmft.buf) + goto fail; + + if (grub_disk_read + (disk, data->mft_start, 0, data->mft_size << BLK_SHR, data->mmft.buf)) + goto fail; + + data->uuid = grub_le_to_cpu64 (bpb.num_serial); + + if (fixup (data, data->mmft.buf, data->mft_size, "FILE")) + goto fail; + + if (!locate_attr (&data->mmft.attr, &data->mmft, AT_DATA)) + goto fail; + + if (init_file (&data->cmft, FILE_ROOT)) + goto fail; + + return data; + +fail: + grub_error (GRUB_ERR_BAD_FS, "not an ntfs filesystem"); + + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + return 0; +} + +static grub_err_t +grub_ntfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + + data = grub_ntfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->cmft, &fdiro, grub_ntfs_iterate_dir, + 0, GRUB_FSHELP_DIR); + + if (grub_errno) + goto fail; + + grub_ntfs_iterate_dir (fdiro, iterate); + +fail: + if ((fdiro) && (fdiro != &data->cmft)) + { + free_file (fdiro); + grub_free (fdiro); + } + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_ntfs_open (grub_file_t file, const char *name) +{ + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *mft = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ntfs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->cmft, &mft, grub_ntfs_iterate_dir, + 0, GRUB_FSHELP_REG); + + if (grub_errno) + goto fail; + + if (mft != &data->cmft) + { + free_file (&data->cmft); + grub_memcpy (&data->cmft, mft, sizeof (*mft)); + grub_free (mft); + if (!data->cmft.inode_read) + { + if (init_file (&data->cmft, data->cmft.ino)) + goto fail; + } + } + + file->size = data->cmft.size; + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_ssize_t +grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_ntfs_file *mft; + + mft = &((struct grub_ntfs_data *) file->data)->cmft; + if (file->read_hook) + mft->attr.save_pos = 1; + + if (file->offset > file->size) + { + grub_error (GRUB_ERR_BAD_FS, "Bad offset"); + return -1; + } + + if (file->offset + len > file->size) + len = file->size - file->offset; + + read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook); + return (grub_errno) ? 0 : len; +} + +static grub_err_t +grub_ntfs_close (grub_file_t file) +{ + struct grub_ntfs_data *data; + + data = file->data; + + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_ntfs_label (grub_device_t device, char **label) +{ + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *mft = 0; + char *pa; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + *label = 0; + + data = grub_ntfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file ("/$Volume", &data->cmft, &mft, grub_ntfs_iterate_dir, + 0, GRUB_FSHELP_REG); + + if (grub_errno) + goto fail; + + if (!mft->inode_read) + { + mft->buf = grub_malloc (mft->data->mft_size << BLK_SHR); + if (mft->buf == NULL) + goto fail; + + if (read_mft (mft->data, mft->buf, mft->ino)) + goto fail; + } + + init_attr (&mft->attr, mft); + pa = find_attr (&mft->attr, AT_VOLUME_NAME); + if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) + { + char *buf; + int len; + + len = u32at (pa, 0x10) / 2; + buf = grub_malloc (len * 4 + 1); + pa += u16at (pa, 0x14); + *grub_utf16_to_utf8 ((grub_uint8_t *) buf, (grub_uint16_t *) pa, len) = + '\0'; + *label = buf; + } + +fail: + if ((mft) && (mft != &data->cmft)) + { + free_file (mft); + grub_free (mft); + } + if (data) + { + free_file (&data->mmft); + free_file (&data->cmft); + grub_free (data); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_ntfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_ntfs_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_ntfs_mount (disk); + if (data) + { + *uuid = grub_malloc (16 + sizeof ('\0')); + grub_sprintf (*uuid, "%016llx", (unsigned long long) data->uuid); + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static struct grub_fs grub_ntfs_fs = { + .name = "ntfs", + .dir = grub_ntfs_dir, + .open = grub_ntfs_open, + .read = grub_ntfs_read, + .close = grub_ntfs_close, + .label = grub_ntfs_label, + .uuid = grub_ntfs_uuid, + .next = 0 +}; + +GRUB_MOD_INIT (ntfs) +{ + grub_fs_register (&grub_ntfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI (ntfs) +{ + grub_fs_unregister (&grub_ntfs_fs); +} diff --git a/fs/ntfscomp.c b/fs/ntfscomp.c new file mode 100644 index 0000000..db8b506 --- /dev/null +++ b/fs/ntfscomp.c @@ -0,0 +1,375 @@ +/* ntfscomp.c - compression support for the NTFS filesystem */ +/* + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +decomp_nextvcn (struct grub_ntfs_comp *cc) +{ + if (cc->comp_head >= cc->comp_tail) + return grub_error (GRUB_ERR_BAD_FS, "Compression block overflown"); + if (grub_disk_read + (cc->disk, + (cc->comp_table[cc->comp_head][1] - + (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0, + cc->spc << BLK_SHR, cc->cbuf)) + return grub_errno; + cc->cbuf_vcn++; + if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0])) + cc->comp_head++; + cc->cbuf_ofs = 0; + return 0; +} + +static grub_err_t +decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) +{ + if (cc->cbuf_ofs >= (cc->spc << BLK_SHR)) + { + if (decomp_nextvcn (cc)) + return grub_errno; + } + *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++]; + return 0; +} + +static grub_err_t +decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res) +{ + unsigned char c1, c2; + + if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2))) + return grub_errno; + *res = ((grub_uint16_t) c2) * 256 + ((grub_uint16_t) c1); + return 0; +} + +/* Decompress a block (4096 bytes) */ +static grub_err_t +decomp_block (struct grub_ntfs_comp *cc, char *dest) +{ + grub_uint16_t flg, cnt; + + if (decomp_get16 (cc, &flg)) + return grub_errno; + cnt = (flg & 0xFFF) + 1; + + if (dest) + { + if (flg & 0x8000) + { + unsigned char tag; + grub_uint32_t bits, copied; + + bits = copied = tag = 0; + while (cnt > 0) + { + if (copied > COM_LEN) + return grub_error (GRUB_ERR_BAD_FS, + "Compression block too large"); + + if (!bits) + { + if (decomp_getch (cc, &tag)) + return grub_errno; + + bits = 8; + cnt--; + if (cnt <= 0) + break; + } + if (tag & 1) + { + grub_uint32_t i, len, delta, code, lmask, dshift; + grub_uint16_t word; + + if (decomp_get16 (cc, &word)) + return grub_errno; + + code = word; + cnt -= 2; + + if (!copied) + { + grub_error (GRUB_ERR_BAD_FS, "Context window empty"); + return 0; + } + + for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10; + i >>= 1) + { + lmask >>= 1; + dshift--; + } + + delta = code >> dshift; + len = (code & lmask) + 3; + + for (i = 0; i < len; i++) + { + dest[copied] = dest[copied - delta - 1]; + copied++; + } + } + else + { + unsigned char ch; + + if (decomp_getch (cc, &ch)) + return grub_errno; + dest[copied++] = ch; + cnt--; + } + tag >>= 1; + bits--; + } + return 0; + } + else + { + if (cnt != COM_LEN) + return grub_error (GRUB_ERR_BAD_FS, + "Invalid compression block size"); + } + } + + while (cnt > 0) + { + int n; + + n = (cc->spc << BLK_SHR) - cc->cbuf_ofs; + if (n > cnt) + n = cnt; + if ((dest) && (n)) + { + memcpy (dest, &cc->cbuf[cc->cbuf_ofs], n); + dest += n; + } + cnt -= n; + cc->cbuf_ofs += n; + if ((cnt) && (decomp_nextvcn (cc))) + return grub_errno; + } + return 0; +} + +static grub_err_t +read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) +{ + int cpb = COM_SEC / ctx->comp.spc; + + while (num) + { + int nn; + + if ((ctx->target_vcn & 0xF) == 0) + { + + if (ctx->comp.comp_head != ctx->comp.comp_tail) + return grub_error (GRUB_ERR_BAD_FS, "Invalid compression block"); + ctx->comp.comp_head = ctx->comp.comp_tail = 0; + ctx->comp.cbuf_vcn = ctx->target_vcn; + ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR); + if (ctx->target_vcn >= ctx->next_vcn) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + } + while (ctx->target_vcn + 16 > ctx->next_vcn) + { + if (ctx->flags & RF_BLNK) + break; + ctx->comp.comp_table[ctx->comp.comp_tail][0] = ctx->next_vcn; + ctx->comp.comp_table[ctx->comp.comp_tail][1] = + ctx->curr_lcn + ctx->next_vcn - ctx->curr_vcn; + ctx->comp.comp_tail++; + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; + } + } + + nn = (16 - (ctx->target_vcn & 0xF)) / cpb; + if (nn > num) + nn = num; + num -= nn; + + if (ctx->flags & RF_BLNK) + { + ctx->target_vcn += nn * cpb; + if (ctx->comp.comp_tail == 0) + { + if (buf) + { + grub_memset (buf, 0, nn * COM_LEN); + buf += nn * COM_LEN; + } + } + else + { + while (nn) + { + if (decomp_block (&ctx->comp, buf)) + return grub_errno; + if (buf) + buf += COM_LEN; + nn--; + } + } + } + else + { + nn *= cpb; + while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn)) + { + int tt; + + tt = + ctx->comp.comp_table[ctx->comp.comp_head][0] - + ctx->target_vcn; + if (tt > nn) + tt = nn; + ctx->target_vcn += tt; + if (buf) + { + if (grub_disk_read + (ctx->comp.disk, + (ctx->comp.comp_table[ctx->comp.comp_head][1] - + (ctx->comp.comp_table[ctx->comp.comp_head][0] - + ctx->target_vcn)) * ctx->comp.spc, 0, + tt * (ctx->comp.spc << BLK_SHR), buf)) + return grub_errno; + buf += tt * (ctx->comp.spc << BLK_SHR); + } + nn -= tt; + if (ctx->target_vcn >= + ctx->comp.comp_table[ctx->comp.comp_head][0]) + ctx->comp.comp_head++; + } + if (nn) + { + if (buf) + { + if (grub_disk_read + (ctx->comp.disk, + (ctx->target_vcn - ctx->curr_vcn + + ctx->curr_lcn) * ctx->comp.spc, 0, + nn * (ctx->comp.spc << BLK_SHR), buf)) + return grub_errno; + buf += nn * (ctx->comp.spc << BLK_SHR); + } + ctx->target_vcn += nn; + } + } + } + return 0; +} + +static grub_err_t +ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_uint32_t ofs, + grub_uint32_t len, struct grub_ntfs_rlst *ctx, grub_uint32_t vcn) +{ + grub_err_t ret; + + ctx->comp.comp_head = ctx->comp.comp_tail = 0; + ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << BLK_SHR); + if (!ctx->comp.cbuf) + return 0; + + ret = 0; + + //ctx->comp.disk->read_hook = read_hook; + + if ((vcn > ctx->target_vcn) && + (read_block + (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / COM_SEC))) + { + ret = grub_errno; + goto quit; + } + + if (ofs % COM_LEN) + { + grub_uint32_t t, n, o; + + t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) + { + ret = grub_errno; + goto quit; + } + + at->save_pos = t; + + o = ofs % COM_LEN; + n = COM_LEN - o; + if (n > len) + n = len; + grub_memcpy (dest, &at->sbuf[o], n); + if (n == len) + goto quit; + dest += n; + len -= n; + } + + if (read_block (ctx, dest, len / COM_LEN)) + { + ret = grub_errno; + goto quit; + } + + dest += (len / COM_LEN) * COM_LEN; + len = len % COM_LEN; + if (len) + { + grub_uint32_t t; + + t = ctx->target_vcn * (ctx->comp.spc << BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) + { + ret = grub_errno; + goto quit; + } + + at->save_pos = t; + + grub_memcpy (dest, at->sbuf, len); + } + +quit: + //ctx->comp.disk->read_hook = 0; + if (ctx->comp.cbuf) + grub_free (ctx->comp.cbuf); + return ret; +} + +GRUB_MOD_INIT (ntfscomp) +{ + (void) mod; + grub_ntfscomp_func = ntfscomp; +} + +GRUB_MOD_FINI (ntfscomp) +{ + grub_ntfscomp_func = NULL; +} diff --git a/fs/reiserfs.c b/fs/reiserfs.c new file mode 100644 index 0000000..8e91149 --- /dev/null +++ b/fs/reiserfs.c @@ -0,0 +1,1399 @@ +/* reiserfs.c - ReiserFS versions up to 3.6 */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + TODO: + implement journal handling (ram replay) + test tail packing & direct files + validate partition label position +*/ + +#if 0 +# define GRUB_REISERFS_DEBUG +# define GRUB_REISERFS_JOURNALING +# define GRUB_HEXDUMP +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIN(a, b) \ + ({ typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + _a < _b ? _a : _b; }) + +#define MAX(a, b) \ + ({ typeof (a) _a = (a); \ + typeof (b) _b = (b); \ + _a > _b ? _a : _b; }) + +#define REISERFS_SUPER_BLOCK_OFFSET 0x10000 +#define REISERFS_MAGIC_LEN 12 +#define REISERFS_MAGIC_STRING "ReIsEr" +#define REISERFS_MAGIC_DESC_BLOCK "ReIsErLB" +/* If the 3rd bit of an item state is set, then it's visible. */ +#define GRUB_REISERFS_VISIBLE_MASK ((grub_uint16_t) 0x04) +#define REISERFS_MAX_LABEL_LENGTH 16 +#define REISERFS_LABEL_OFFSET 0x64 + +#define S_IFLNK 0xA000 + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +#define assert(boolean) real_assert (boolean, __FILE__, __LINE__) +static inline void +real_assert (int boolean, const char *file, const int line) +{ + if (! boolean) + grub_printf ("Assertion failed at %s:%d\n", file, line); +} + +enum grub_reiserfs_item_type + { + GRUB_REISERFS_STAT, + GRUB_REISERFS_DIRECTORY, + GRUB_REISERFS_DIRECT, + GRUB_REISERFS_INDIRECT, + /* Matches both _DIRECT and _INDIRECT when searching. */ + GRUB_REISERFS_ANY, + GRUB_REISERFS_UNKNOWN + }; + +struct grub_reiserfs_superblock +{ + grub_uint32_t block_count; + grub_uint32_t block_free_count; + grub_uint32_t root_block; + grub_uint32_t journal_block; + grub_uint32_t journal_device; + grub_uint32_t journal_original_size; + grub_uint32_t journal_max_transaction_size; + grub_uint32_t journal_block_count; + grub_uint32_t journal_max_batch; + grub_uint32_t journal_max_commit_age; + grub_uint32_t journal_max_transaction_age; + grub_uint16_t block_size; + grub_uint16_t oid_max_size; + grub_uint16_t oid_current_size; + grub_uint16_t state; + grub_uint8_t magic_string[REISERFS_MAGIC_LEN]; + grub_uint32_t function_hash_code; + grub_uint16_t tree_height; + grub_uint16_t bitmap_number; + grub_uint16_t version; + grub_uint16_t reserved; + grub_uint32_t inode_generation; + grub_uint8_t unused[4]; + grub_uint16_t uuid[8]; +} __attribute__ ((packed)); + +struct grub_reiserfs_journal_header +{ + grub_uint32_t last_flush_uid; + grub_uint32_t unflushed_offset; + grub_uint32_t mount_id; +} __attribute__ ((packed)); + +struct grub_reiserfs_description_block +{ + grub_uint32_t id; + grub_uint32_t len; + grub_uint32_t mount_id; + grub_uint32_t real_blocks[0]; +} __attribute__ ((packed)); + +struct grub_reiserfs_commit_block +{ + grub_uint32_t id; + grub_uint32_t len; + grub_uint32_t real_blocks[0]; +} __attribute__ ((packed)); + +struct grub_reiserfs_stat_item_v1 +{ + grub_uint16_t mode; + grub_uint16_t hardlink_count; + grub_uint16_t uid; + grub_uint16_t gid; + grub_uint32_t size; + grub_uint32_t atime; + grub_uint32_t mtime; + grub_uint32_t ctime; + grub_uint32_t rdev; + grub_uint32_t first_direct_byte; +} __attribute__ ((packed)); + +struct grub_reiserfs_stat_item_v2 +{ + grub_uint16_t mode; + grub_uint16_t reserved; + grub_uint32_t hardlink_count; + grub_uint64_t size; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t atime; + grub_uint32_t mtime; + grub_uint32_t ctime; + grub_uint32_t blocks; + grub_uint32_t first_direct_byte; +} __attribute__ ((packed)); + +struct grub_reiserfs_key +{ + grub_uint32_t directory_id; + grub_uint32_t object_id; + union + { + struct + { + grub_uint32_t offset; + grub_uint32_t type; + } v1 __attribute__ ((packed)); + struct + { + grub_uint64_t offset_type; + } v2 __attribute__ ((packed)); + } u; +} __attribute__ ((packed)); + +struct grub_reiserfs_item_header +{ + struct grub_reiserfs_key key; + union + { + grub_uint16_t free_space; + grub_uint16_t entry_count; + } u __attribute__ ((packed)); + grub_uint16_t item_size; + grub_uint16_t item_location; + grub_uint16_t version; +} __attribute__ ((packed)); + +struct grub_reiserfs_block_header +{ + grub_uint16_t level; + grub_uint16_t item_count; + grub_uint16_t free_space; + grub_uint16_t reserved; + struct grub_reiserfs_key block_right_delimiting_key; +} __attribute__ ((packed)); + +struct grub_reiserfs_disk_child +{ + grub_uint32_t block_number; + grub_uint16_t size; + grub_uint16_t reserved; +} __attribute__ ((packed)); + +struct grub_reiserfs_directory_header +{ + grub_uint32_t offset; + grub_uint32_t directory_id; + grub_uint32_t object_id; + grub_uint16_t location; + grub_uint16_t state; +} __attribute__ ((packed)); + +struct grub_fshelp_node +{ + struct grub_reiserfs_data *data; + grub_uint32_t block_number; /* 0 if node is not found. */ + grub_uint16_t block_position; + grub_uint64_t next_offset; + enum grub_reiserfs_item_type type; /* To know how to read the header. */ + struct grub_reiserfs_item_header header; +}; + +/* Returned when opening a file. */ +struct grub_reiserfs_data +{ + struct grub_reiserfs_superblock superblock; + grub_disk_t disk; +}; + +/* Internal-only functions. Not to be used outside of this file. */ + +/* Return the type of given v2 key. */ +static enum grub_reiserfs_item_type +grub_reiserfs_get_key_v2_type (const struct grub_reiserfs_key *key) +{ + switch (grub_le_to_cpu64 (key->u.v2.offset_type) >> 60) + { + case 0: + return GRUB_REISERFS_STAT; + case 15: + return GRUB_REISERFS_ANY; + case 3: + return GRUB_REISERFS_DIRECTORY; + case 2: + return GRUB_REISERFS_DIRECT; + case 1: + return GRUB_REISERFS_INDIRECT; + } + return GRUB_REISERFS_UNKNOWN; +} + +/* Return the type of given v1 key. */ +static enum grub_reiserfs_item_type +grub_reiserfs_get_key_v1_type (const struct grub_reiserfs_key *key) +{ + switch (grub_le_to_cpu32 (key->u.v1.type)) + { + case 0: + return GRUB_REISERFS_STAT; + case 555: + return GRUB_REISERFS_ANY; + case 500: + return GRUB_REISERFS_DIRECTORY; + case 0x20000000: + case 0xFFFFFFFF: + return GRUB_REISERFS_DIRECT; + case 0x10000000: + case 0xFFFFFFFE: + return GRUB_REISERFS_INDIRECT; + } + return GRUB_REISERFS_UNKNOWN; +} + +/* Return 1 if the given key is version 1 key, 2 otherwise. */ +static int +grub_reiserfs_get_key_version (const struct grub_reiserfs_key *key) +{ + return grub_reiserfs_get_key_v1_type (key) == GRUB_REISERFS_UNKNOWN ? 2 : 1; +} + +#ifdef GRUB_HEXDUMP +static void +grub_hexdump (char *buffer, grub_size_t len) +{ + grub_size_t a; + for (a = 0; a < len; a++) + { + if (! (a & 0x0F)) + grub_printf ("\n%08x ", a); + grub_printf ("%02x ", + ((unsigned int) ((unsigned char *) buffer)[a]) & 0xFF); + } + grub_printf ("\n"); +} +#endif + +#ifdef GRUB_REISERFS_DEBUG +static grub_uint64_t +grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key); + +static enum grub_reiserfs_item_type +grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key); + +static void +grub_reiserfs_print_key (const struct grub_reiserfs_key *key) +{ + unsigned int a; + char *reiserfs_type_strings[] = { + "stat ", + "directory", + "direct ", + "indirect ", + "any ", + "unknown " + }; + + for (a = 0; a < sizeof (struct grub_reiserfs_key); a++) + grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF); + grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ", + grub_le_to_cpu32 (key->directory_id), + grub_le_to_cpu32 (key->object_id), + reiserfs_type_strings [grub_reiserfs_get_key_type (key)]); + if (grub_reiserfs_get_key_version (key) == 1) + grub_printf("%08x", (unsigned int) grub_reiserfs_get_key_offset (key)); + else + grub_printf("0x%07x%08x", + (unsigned) (grub_reiserfs_get_key_offset (key) >> 32), + (unsigned) (grub_reiserfs_get_key_offset (key) & 0xFFFFFFFF)); + grub_printf ("\n"); +} +#endif + +/* Return the offset of given key. */ +static grub_uint64_t +grub_reiserfs_get_key_offset (const struct grub_reiserfs_key *key) +{ + if (grub_reiserfs_get_key_version (key) == 1) + return grub_le_to_cpu32 (key->u.v1.offset); + else + return grub_le_to_cpu64 (key->u.v2.offset_type) & (~0ULL >> 4); +} + +/* Set the offset of given key. */ +static void +grub_reiserfs_set_key_offset (struct grub_reiserfs_key *key, + grub_uint64_t value) +{ + if (grub_reiserfs_get_key_version (key) == 1) + key->u.v1.offset = grub_cpu_to_le32 (value); + else + key->u.v2.offset_type \ + = ((key->u.v2.offset_type & grub_cpu_to_le64 (15ULL << 60)) + | grub_cpu_to_le64 (value & (~0ULL >> 4))); +} + +/* Return the type of given key. */ +static enum grub_reiserfs_item_type +grub_reiserfs_get_key_type (const struct grub_reiserfs_key *key) +{ + if (grub_reiserfs_get_key_version (key) == 1) + return grub_reiserfs_get_key_v1_type (key); + else + return grub_reiserfs_get_key_v2_type (key); +} + +/* Set the type of given key, with given version number. */ +static void +grub_reiserfs_set_key_type (struct grub_reiserfs_key *key, + enum grub_reiserfs_item_type grub_type, + int version) +{ + grub_uint32_t type; + + switch (grub_type) + { + case GRUB_REISERFS_STAT: + type = 0; + break; + case GRUB_REISERFS_ANY: + type = (version == 1) ? 555 : 15; + break; + case GRUB_REISERFS_DIRECTORY: + type = (version == 1) ? 500 : 3; + break; + case GRUB_REISERFS_DIRECT: + type = (version == 1) ? 0xFFFFFFFF : 2; + break; + case GRUB_REISERFS_INDIRECT: + type = (version == 1) ? 0xFFFFFFFE : 1; + break; + default: + return; + } + + if (version == 1) + key->u.v1.type = grub_cpu_to_le32 (type); + else + key->u.v2.offset_type + = ((key->u.v2.offset_type & grub_cpu_to_le64 (~0ULL >> 4)) + | grub_cpu_to_le64 ((grub_uint64_t) type << 60)); + + assert (grub_reiserfs_get_key_type (key) == grub_type); +} + +/* -1 if key 1 if lower than key 2. + 0 if key 1 is equal to key 2. + 1 if key 1 is higher than key 2. */ +static int +grub_reiserfs_compare_keys (const struct grub_reiserfs_key *key1, + const struct grub_reiserfs_key *key2) +{ + grub_uint64_t offset1, offset2; + enum grub_reiserfs_item_type type1, type2; + grub_uint32_t id1, id2; + + if (! key1 || ! key2) + return -2; + + id1 = grub_le_to_cpu32 (key1->directory_id); + id2 = grub_le_to_cpu32 (key2->directory_id); + if (id1 < id2) + return -1; + if (id1 > id2) + return 1; + + id1 = grub_le_to_cpu32 (key1->object_id); + id2 = grub_le_to_cpu32 (key2->object_id); + if (id1 < id2) + return -1; + if (id1 > id2) + return 1; + + offset1 = grub_reiserfs_get_key_offset (key1); + offset2 = grub_reiserfs_get_key_offset (key2); + if (offset1 < offset2) + return -1; + if (offset1 > offset2) + return 1; + + type1 = grub_reiserfs_get_key_type (key1); + type2 = grub_reiserfs_get_key_type (key2); + if ((type1 == GRUB_REISERFS_ANY + && (type2 == GRUB_REISERFS_DIRECT + || type2 == GRUB_REISERFS_INDIRECT)) + || (type2 == GRUB_REISERFS_ANY + && (type1 == GRUB_REISERFS_DIRECT + || type1 == GRUB_REISERFS_INDIRECT))) + return 0; + if (type1 < type2) + return -1; + if (type1 > type2) + return 1; + + return 0; +} + +/* Find the item identified by KEY in mounted filesystem DATA, and fill ITEM + accordingly to what was found. */ +static grub_err_t +grub_reiserfs_get_item (struct grub_reiserfs_data *data, + const struct grub_reiserfs_key *key, + struct grub_fshelp_node *item) +{ + grub_uint32_t block_number; + struct grub_reiserfs_block_header *block_header = 0; + struct grub_reiserfs_key *block_key = 0; + grub_uint16_t block_size, item_count, current_level; + grub_uint16_t i; + grub_uint16_t previous_level = ~0; + struct grub_reiserfs_item_header *item_headers = 0; + + if (! data) + { + grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL"); + goto fail; + } + + if (! key) + { + grub_error (GRUB_ERR_TEST_FAILURE, "key is NULL"); + goto fail; + } + + if (! item) + { + grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL"); + goto fail; + } + + block_size = grub_le_to_cpu16 (data->superblock.block_size); + block_number = grub_le_to_cpu32 (data->superblock.root_block); +#ifdef GRUB_REISERFS_DEBUG + grub_printf("Searching for "); + grub_reiserfs_print_key (key); +#endif + block_header = grub_malloc (block_size); + if (! block_header) + goto fail; + + item->next_offset = 0; + do + { + grub_disk_read (data->disk, + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + (((grub_off_t) block_number * block_size) + & (GRUB_DISK_SECTOR_SIZE - 1)), + block_size, (char *) block_header); + if (grub_errno) + goto fail; + current_level = grub_le_to_cpu16 (block_header->level); + grub_dprintf ("reiserfs_tree", " at level %d\n", current_level); + if (current_level >= previous_level) + { + grub_dprintf ("reiserfs_tree", "level loop detected, aborting\n"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "level loop"); + goto fail; + } + previous_level = current_level; + item_count = grub_le_to_cpu16 (block_header->item_count); + grub_dprintf ("reiserfs_tree", " number of contained items : %d\n", + item_count); + if (current_level > 1) + { + /* Internal node. Navigate to the child that should contain + the searched key. */ + struct grub_reiserfs_key *keys + = (struct grub_reiserfs_key *) (block_header + 1); + struct grub_reiserfs_disk_child *children + = ((struct grub_reiserfs_disk_child *) + (keys + item_count)); + + for (i = 0; + i < item_count + && grub_reiserfs_compare_keys (key, &(keys[i])) >= 0; + i++) + { +#ifdef GRUB_REISERFS_DEBUG + grub_printf("i %03d/%03d ", i + 1, item_count + 1); + grub_reiserfs_print_key (&(keys[i])); +#endif + } + block_number = grub_le_to_cpu32 (children[i].block_number); + if ((i < item_count) && (key->directory_id == keys[i].directory_id) + && (key->object_id == keys[i].object_id)) + item->next_offset = grub_reiserfs_get_key_offset(&(keys[i])); +#ifdef GRUB_REISERFS_DEBUG + if (i == item_count + || grub_reiserfs_compare_keys (key, &(keys[i])) == 0) + grub_printf(">"); + else + grub_printf("<"); + if (i < item_count) + { + grub_printf (" %03d/%03d ", i + 1, item_count + 1); + grub_reiserfs_print_key (&(keys[i])); + if (i + 1 < item_count) + { + grub_printf ("+ %03d/%03d ", i + 2, item_count); + grub_reiserfs_print_key (&(keys[i + 1])); + } + } + else + grub_printf ("Accessing rightmost child at block %d.\n", + block_number); +#endif + } + else + { + /* Leaf node. Check that the key is actually present. */ + item_headers + = (struct grub_reiserfs_item_header *) (block_header + 1); + for (i = 0; + i < item_count + && (grub_reiserfs_compare_keys (key, &(item_headers[i].key)) + != 0); + i++) + { +#ifdef GRUB_REISERFS_DEBUG + if (key->directory_id == item_headers[i].key.directory_id && \ + key->object_id == item_headers[i].key.object_id) + grub_printf("C"); + else + grub_printf(" "); + grub_printf(" %03d/%03d ", i + 1, item_count); + grub_reiserfs_print_key (&(item_headers[i].key)); +#endif + } + if (i < item_count) + block_key = &(item_headers[i].key); + } + } + while (current_level > 1); + + item->data = data; + + if (i == item_count || grub_reiserfs_compare_keys (key, block_key)) + { + item->block_number = 0; + item->block_position = 0; + item->type = GRUB_REISERFS_UNKNOWN; +#ifdef GRUB_REISERFS_DEBUG + grub_printf("Not found.\n"); +#endif + } + else + { + item->block_number = block_number; + item->block_position = i; + item->type = grub_reiserfs_get_key_type (block_key); + grub_memcpy (&(item->header), &(item_headers[i]), + sizeof (struct grub_reiserfs_item_header)); +#ifdef GRUB_REISERFS_DEBUG + grub_printf ("F %03d/%03d ", i + 1, item_count); + grub_reiserfs_print_key (block_key); +#endif + } + + assert (grub_errno == GRUB_ERR_NONE); + grub_free (block_header); + return GRUB_ERR_NONE; + + fail: + assert (grub_errno != GRUB_ERR_NONE); + grub_free (block_header); + assert (grub_errno != GRUB_ERR_NONE); + return grub_errno; +} + +/* Return the path of the file which is pointed at by symlink NODE. */ +static char * +grub_reiserfs_read_symlink (grub_fshelp_node_t node) +{ + char *symlink_buffer = 0; + grub_uint16_t block_size; + grub_disk_addr_t block; + grub_off_t offset; + grub_size_t len; + struct grub_fshelp_node found; + struct grub_reiserfs_key key; + + grub_memcpy (&key, &(node->header.key), sizeof (key)); + grub_reiserfs_set_key_offset (&key, 1); + grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECT, + grub_reiserfs_get_key_version (&key)); + + if (grub_reiserfs_get_item (node->data, &key, &found) != GRUB_ERR_NONE) + goto fail; + + if (found.block_number == 0) + goto fail; + + block_size = grub_le_to_cpu16 (node->data->superblock.block_size); + len = grub_le_to_cpu16 (found.header.item_size); + block = found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS); + offset = grub_le_to_cpu16 (found.header.item_location); + + symlink_buffer = grub_malloc (len + 1); + if (! symlink_buffer) + goto fail; + + grub_disk_read (node->data->disk, block, offset, len, symlink_buffer); + if (grub_errno) + goto fail; + + symlink_buffer[len] = 0; + return symlink_buffer; + + fail: + grub_free (symlink_buffer); + return 0; +} + +/* Fill the mounted filesystem structure and return it. */ +static struct grub_reiserfs_data * +grub_reiserfs_mount (grub_disk_t disk) +{ + struct grub_reiserfs_data *data = 0; + data = grub_malloc (sizeof (*data)); + if (! data) + goto fail; + grub_disk_read (disk, REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE, + 0, sizeof (data->superblock), (char *) &(data->superblock)); + if (grub_errno) + goto fail; + if (grub_memcmp (data->superblock.magic_string, + REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1)) + { + grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem"); + goto fail; + } + data->disk = disk; + return data; + + fail: + /* Disk is too small to contain a ReiserFS. */ + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem"); + + grub_free (data); + return 0; +} + +/* Call HOOK for each file in directory ITEM. */ +static int +grub_reiserfs_iterate_dir (grub_fshelp_node_t item, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + struct grub_reiserfs_data *data = item->data; + struct grub_reiserfs_block_header *block_header = 0; + grub_uint16_t block_size, block_position; + grub_uint32_t block_number; + grub_uint64_t next_offset = item->next_offset; + int ret = 0; + + if (item->type != GRUB_REISERFS_DIRECTORY) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "grub_reiserfs_iterate_dir called on a non-directory item"); + goto fail; + } + block_size = grub_le_to_cpu16 (data->superblock.block_size); + block_header = grub_malloc (block_size); + if (! block_header) + goto fail; + block_number = item->block_number; + block_position = item->block_position; + grub_dprintf ("reiserfs", "Iterating directory...\n"); + do + { + struct grub_reiserfs_directory_header *directory_headers; + struct grub_fshelp_node directory_item; + grub_uint16_t entry_count, entry_number; + struct grub_reiserfs_item_header *item_headers; + + grub_disk_read (data->disk, + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + (((grub_off_t) block_number * block_size) + & (GRUB_DISK_SECTOR_SIZE - 1)), + block_size, (char *) block_header); + if (grub_errno) + goto fail; + +#if 0 + if (grub_le_to_cpu16 (block_header->level) != 1) + { + grub_error (GRUB_ERR_TEST_FAILURE, + "reiserfs: block %d is not a leaf block", + block_number); + goto fail; + } +#endif + + item_headers = (struct grub_reiserfs_item_header *) (block_header + 1); + directory_headers + = ((struct grub_reiserfs_directory_header *) + ((char *) block_header + + grub_le_to_cpu16 (item_headers[block_position].item_location))); + entry_count + = grub_le_to_cpu16 (item_headers[block_position].u.entry_count); + for (entry_number = 0; entry_number < entry_count; entry_number++) + { + struct grub_reiserfs_directory_header *directory_header + = &directory_headers[entry_number]; + grub_uint16_t entry_state + = grub_le_to_cpu16 (directory_header->state); + + if (entry_state & GRUB_REISERFS_VISIBLE_MASK) + { + grub_fshelp_node_t entry_item; + struct grub_reiserfs_key entry_key; + enum grub_reiserfs_item_type entry_type; + char *entry_name; + + entry_name = (((char *) directory_headers) + + grub_le_to_cpu16 (directory_header->location)); + entry_key.directory_id = directory_header->directory_id; + entry_key.object_id = directory_header->object_id; + entry_key.u.v2.offset_type = 0; + grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_DIRECTORY, + 2); + grub_reiserfs_set_key_offset (&entry_key, 1); + + entry_item = grub_malloc (sizeof (*entry_item)); + if (! entry_item) + goto fail; + + if (grub_reiserfs_get_item (data, &entry_key, entry_item) + != GRUB_ERR_NONE) + { + grub_free (entry_item); + goto fail; + } + + if (entry_item->type == GRUB_REISERFS_DIRECTORY) + entry_type = GRUB_FSHELP_DIR; + else + { + grub_uint32_t entry_block_number; + /* Order is very important here. + First set the offset to 0 using current key version. + Then change the key type, which influes on key version + detection. */ + grub_reiserfs_set_key_offset (&entry_key, 0); + grub_reiserfs_set_key_type (&entry_key, GRUB_REISERFS_STAT, + 2); + if (grub_reiserfs_get_item (data, &entry_key, entry_item) + != GRUB_ERR_NONE) + { + grub_free (entry_item); + goto fail; + } + + if (entry_item->block_number != 0) + { + grub_uint16_t entry_version; + entry_version + = grub_le_to_cpu16 (entry_item->header.version); + entry_block_number = entry_item->block_number; +#if 0 + grub_dprintf ("reiserfs", + "version %04x block %08x (%08x) position %08x\n", + entry_version, entry_block_number, + ((grub_disk_addr_t) entry_block_number * block_size) / GRUB_DISK_SECTOR_SIZE, + grub_le_to_cpu16 (entry_item->header.item_location)); +#endif + if (entry_version == 0) /* Version 1 stat item. */ + { + struct grub_reiserfs_stat_item_v1 entry_v1_stat; + grub_disk_read (data->disk, + entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + grub_le_to_cpu16 (entry_item->header.item_location), + sizeof (entry_v1_stat), + (char *) &entry_v1_stat); + if (grub_errno) + goto fail; +#if 0 + grub_dprintf ("reiserfs", + "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n", + grub_le_to_cpu16 (entry_v1_stat.mode), + grub_le_to_cpu16 (entry_v1_stat.hardlink_count), + grub_le_to_cpu16 (entry_v1_stat.uid), + grub_le_to_cpu16 (entry_v1_stat.gid), + grub_le_to_cpu32 (entry_v1_stat.size), + grub_le_to_cpu32 (entry_v1_stat.atime), + grub_le_to_cpu32 (entry_v1_stat.mtime), + grub_le_to_cpu32 (entry_v1_stat.ctime), + grub_le_to_cpu32 (entry_v1_stat.rdev), + grub_le_to_cpu32 (entry_v1_stat.first_direct_byte)); + grub_dprintf ("reiserfs", + "%04x %04x %04x %04x %08x %08x | %08x %08x %08x %08x\n", + entry_v1_stat.mode, + entry_v1_stat.hardlink_count, + entry_v1_stat.uid, + entry_v1_stat.gid, + entry_v1_stat.size, + entry_v1_stat.atime, + entry_v1_stat.mtime, + entry_v1_stat.ctime, + entry_v1_stat.rdev, + entry_v1_stat.first_direct_byte); +#endif + if ((grub_le_to_cpu16 (entry_v1_stat.mode) & S_IFLNK) + == S_IFLNK) + entry_type = GRUB_FSHELP_SYMLINK; + else + entry_type = GRUB_FSHELP_REG; + } + else + { + struct grub_reiserfs_stat_item_v2 entry_v2_stat; + grub_disk_read (data->disk, + entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + grub_le_to_cpu16 (entry_item->header.item_location), + sizeof (entry_v2_stat), + (char *) &entry_v2_stat); + if (grub_errno) + goto fail; +#if 0 + grub_dprintf ("reiserfs", + "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n", + grub_le_to_cpu16 (entry_v2_stat.mode), + grub_le_to_cpu16 (entry_v2_stat.reserved), + grub_le_to_cpu32 (entry_v2_stat.hardlink_count), + (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) >> 32), + (unsigned int) (grub_le_to_cpu64 (entry_v2_stat.size) && 0xFFFFFFFF), + grub_le_to_cpu32 (entry_v2_stat.uid), + grub_le_to_cpu32 (entry_v2_stat.gid), + grub_le_to_cpu32 (entry_v2_stat.atime), + grub_le_to_cpu32 (entry_v2_stat.mtime), + grub_le_to_cpu32 (entry_v2_stat.ctime), + grub_le_to_cpu32 (entry_v2_stat.blocks), + grub_le_to_cpu32 (entry_v2_stat.first_direct_byte)); + grub_dprintf ("reiserfs", + "%04x %04x %08x %08x%08x | %08x %08x %08x %08x | %08x %08x %08x\n", + entry_v2_stat.mode, + entry_v2_stat.reserved, + entry_v2_stat.hardlink_count, + (unsigned int) (entry_v2_stat.size >> 32), + (unsigned int) (entry_v2_stat.size && 0xFFFFFFFF), + entry_v2_stat.uid, + entry_v2_stat.gid, + entry_v2_stat.atime, + entry_v2_stat.mtime, + entry_v2_stat.ctime, + entry_v2_stat.blocks, + entry_v2_stat.first_direct_byte); +#endif + if ((grub_le_to_cpu16 (entry_v2_stat.mode) & S_IFLNK) + == S_IFLNK) + entry_type = GRUB_FSHELP_SYMLINK; + else + entry_type = GRUB_FSHELP_REG; + } + } + else + { + /* Pseudo file ".." never has stat block. */ + if (grub_strcmp (entry_name, "..")) + grub_dprintf ("reiserfs", + "Warning : %s has no stat block !\n", + entry_name); + grub_free (entry_item); + continue; + } + } + if (hook (entry_name, entry_type, entry_item)) + { + grub_dprintf ("reiserfs", "Found : %s, type=%d\n", + entry_name, entry_type); + ret = 1; + goto found; + } + + *entry_name = 0; /* Make sure next entry name (which is just + before this one in disk order) stops before + the current one. */ + } + } + + if (next_offset == 0) + break; + + grub_reiserfs_set_key_offset (&(item_headers[block_position].key), + next_offset); + if (grub_reiserfs_get_item (data, &(item_headers[block_position].key), + &directory_item) != GRUB_ERR_NONE) + goto fail; + block_number = directory_item.block_number; + block_position = directory_item.block_position; + next_offset = directory_item.next_offset; + } + while (block_number); + + found: + assert (grub_errno == GRUB_ERR_NONE); + grub_free (block_header); + return ret; + fail: + assert (grub_errno != GRUB_ERR_NONE); + grub_free (block_header); + return 0; +} + +/****************************************************************************/ +/* grub api functions */ +/****************************************************************************/ + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_reiserfs_open (struct grub_file *file, const char *name) +{ + struct grub_reiserfs_data *data = 0; + struct grub_fshelp_node root, *found = 0, info; + struct grub_reiserfs_key key; + grub_uint32_t block_number; + grub_uint16_t entry_version, block_size, entry_location; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + data = grub_reiserfs_mount (file->device->disk); + if (! data) + goto fail; + block_size = grub_le_to_cpu16 (data->superblock.block_size); + key.directory_id = grub_cpu_to_le32 (1); + key.object_id = grub_cpu_to_le32 (2); + key.u.v2.offset_type = 0; + grub_reiserfs_set_key_type (&key, GRUB_REISERFS_DIRECTORY, 2); + grub_reiserfs_set_key_offset (&key, 1); + if (grub_reiserfs_get_item (data, &key, &root) != GRUB_ERR_NONE) + goto fail; + if (root.block_number == 0) + { + grub_error (GRUB_ERR_BAD_FS, "Unable to find root item"); + goto fail; /* Should never happen since checked at mount. */ + } + grub_fshelp_find_file (name, &root, &found, + grub_reiserfs_iterate_dir, + grub_reiserfs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + key.directory_id = found->header.key.directory_id; + key.object_id = found->header.key.object_id; + grub_reiserfs_set_key_type (&key, GRUB_REISERFS_STAT, 2); + grub_reiserfs_set_key_offset (&key, 0); + if (grub_reiserfs_get_item (data, &key, &info) != GRUB_ERR_NONE) + goto fail; + if (info.block_number == 0) + { + grub_error (GRUB_ERR_BAD_FS, "Unable to find searched item"); + goto fail; + } + entry_version = grub_le_to_cpu16 (info.header.version); + entry_location = grub_le_to_cpu16 (info.header.item_location); + block_number = info.block_number; + if (entry_version == 0) /* Version 1 stat item. */ + { + struct grub_reiserfs_stat_item_v1 entry_v1_stat; + grub_disk_read (data->disk, + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + entry_location + + (((grub_off_t) block_number * block_size) + & (GRUB_DISK_SECTOR_SIZE - 1)), + sizeof (entry_v1_stat), (char *) &entry_v1_stat); + if (grub_errno) + goto fail; + file->size = (grub_off_t) grub_le_to_cpu64 (entry_v1_stat.size); + } + else + { + struct grub_reiserfs_stat_item_v2 entry_v2_stat; + grub_disk_read (data->disk, + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + entry_location + + (((grub_off_t) block_number * block_size) + & (GRUB_DISK_SECTOR_SIZE - 1)), + sizeof (entry_v2_stat), (char *) &entry_v2_stat); + if (grub_errno) + goto fail; + file->size = (grub_off_t) grub_le_to_cpu64 (entry_v2_stat.size); + } + grub_dprintf ("reiserfs", "file size : %d (%08x%08x)\n", + (unsigned int) file->size, + (unsigned int) (file->size >> 32), (unsigned int) file->size); + file->offset = 0; + file->data = found; + return GRUB_ERR_NONE; + + fail: + assert (grub_errno != GRUB_ERR_NONE); + grub_free (found); + grub_free (data); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return grub_errno; +} + +static grub_ssize_t +grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + unsigned int indirect_block, indirect_block_count; + struct grub_reiserfs_key key; + struct grub_fshelp_node *node = file->data; + struct grub_reiserfs_data *data = node->data; + struct grub_fshelp_node found; + grub_uint16_t block_size = grub_le_to_cpu16 (data->superblock.block_size); + grub_uint16_t item_size; + grub_uint32_t *indirect_block_ptr = 0; + grub_uint64_t current_key_offset = 1; + grub_off_t initial_position, current_position, final_position, length; + grub_disk_addr_t block; + grub_off_t offset; + + if (file->offset >= file->size) + return 0; + + key.directory_id = node->header.key.directory_id; + key.object_id = node->header.key.object_id; + key.u.v2.offset_type = 0; + grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2); + initial_position = file->offset; + current_position = 0; + final_position = MIN (len + initial_position, file->size); + grub_dprintf ("reiserfs", + "Reading from %lld to %lld (%lld instead of requested %ld)\n", + (unsigned long long) initial_position, + (unsigned long long) final_position, + (unsigned long long) (final_position - initial_position), + (unsigned long) len); + while (current_position < final_position) + { + grub_reiserfs_set_key_offset (&key, current_key_offset); + + if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE) + goto fail; + if (found.block_number == 0) + goto fail; + item_size = grub_le_to_cpu16 (found.header.item_size); + switch (found.type) + { + case GRUB_REISERFS_DIRECT: + block = found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS); + grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block); + if (initial_position < current_position + item_size) + { + offset = MAX ((signed) (initial_position - current_position), 0); + length = (MIN (item_size, final_position - current_position) + - offset); + grub_dprintf ("reiserfs", + "Reading direct block %u from %u to %u...\n", + (unsigned) block, (unsigned) offset, + (unsigned) (offset + length)); + found.data->disk->read_hook = file->read_hook; + grub_disk_read (found.data->disk, + block, + offset + + grub_le_to_cpu16 (found.header.item_location), + length, buf); + found.data->disk->read_hook = 0; + if (grub_errno) + goto fail; + buf += length; + current_position += offset + length; + } + else + current_position += item_size; + break; + case GRUB_REISERFS_INDIRECT: + indirect_block_count = item_size / sizeof (*indirect_block_ptr); + indirect_block_ptr = grub_malloc (item_size); + if (! indirect_block_ptr) + goto fail; + grub_disk_read (found.data->disk, + found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS), + grub_le_to_cpu16 (found.header.item_location), + item_size, (char *) indirect_block_ptr); + if (grub_errno) + goto fail; + found.data->disk->read_hook = file->read_hook; + for (indirect_block = 0; + indirect_block < indirect_block_count + && current_position < final_position; + indirect_block++) + { + block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * + (block_size >> GRUB_DISK_SECTOR_BITS); + grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block); + if (current_position + block_size >= initial_position) + { + offset = MAX ((signed) (initial_position - current_position), + 0); + length = (MIN (block_size, final_position - current_position) + - offset); + grub_dprintf ("reiserfs", + "Reading indirect block %u from %u to %u...\n", + (unsigned) block, (unsigned) offset, + (unsigned) (offset + length)); +#if 0 + grub_dprintf ("reiserfs", + "\nib=%04d/%04d, ip=%d, cp=%d, fp=%d, off=%d, l=%d, tl=%d\n", + indirect_block + 1, indirect_block_count, + initial_position, current_position, + final_position, offset, length, len); +#endif + grub_disk_read (found.data->disk, block, offset, length, buf); + if (grub_errno) + goto fail; + buf += length; + current_position += offset + length; + } + else + current_position += block_size; + } + found.data->disk->read_hook = 0; + grub_free (indirect_block_ptr); + indirect_block_ptr = 0; + break; + default: + goto fail; + } + current_key_offset = current_position + 1; + } + + grub_dprintf ("reiserfs", + "Have successfully read %lld bytes (%ld requested)\n", + (unsigned long long) (current_position - initial_position), + (unsigned long) len); + return current_position - initial_position; +/* + switch (found.type) + { + case GRUB_REISERFS_DIRECT: + read_length = MIN (len, item_size - file->offset); + grub_disk_read (found.data->disk, + (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE, + grub_le_to_cpu16 (found.header.item_location) + file->offset, + read_length, buf); + if (grub_errno) + goto fail; + break; + case GRUB_REISERFS_INDIRECT: + indirect_block_count = item_size / sizeof (*indirect_block_ptr); + indirect_block_ptr = grub_malloc (item_size); + if (!indirect_block_ptr) + goto fail; + grub_disk_read (found.data->disk, + (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE, + grub_le_to_cpu16 (found.header.item_location), + item_size, (char *) indirect_block_ptr); + if (grub_errno) + goto fail; + len = MIN (len, file->size - file->offset); + for (indirect_block = file->offset / block_size; + indirect_block < indirect_block_count && read_length < len; + indirect_block++) + { + read = MIN (block_size, len - read_length); + grub_disk_read (found.data->disk, + (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE, + file->offset % block_size, read, + ((void *) buf) + read_length); + if (grub_errno) + goto fail; + read_length += read; + } + grub_free (indirect_block_ptr); + break; + default: + goto fail; + } + + return read_length;*/ + + fail: + grub_free (indirect_block_ptr); + return 0; +} + +/* Close the file FILE. */ +static grub_err_t +grub_reiserfs_close (grub_file_t file) +{ + struct grub_fshelp_node *node = file->data; + struct grub_reiserfs_data *data = node->data; + + grub_free (data); + grub_free (node); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return GRUB_ERR_NONE; +} + +/* Call HOOK with each file under DIR. */ +static grub_err_t +grub_reiserfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_reiserfs_data *data = 0; + struct grub_fshelp_node root, *found; + struct grub_reiserfs_key root_key; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + } +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + data = grub_reiserfs_mount (device->disk); + if (! data) + goto fail; + root_key.directory_id = grub_cpu_to_le32 (1); + root_key.object_id = grub_cpu_to_le32 (2); + root_key.u.v2.offset_type = 0; + grub_reiserfs_set_key_type (&root_key, GRUB_REISERFS_DIRECTORY, 2); + grub_reiserfs_set_key_offset (&root_key, 1); + if (grub_reiserfs_get_item (data, &root_key, &root) != GRUB_ERR_NONE) + goto fail; + if (root.block_number == 0) + { + grub_error(GRUB_ERR_BAD_FS, "Root not found"); + goto fail; + } + grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir, + grub_reiserfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + grub_reiserfs_iterate_dir (found, iterate); + grub_free (data); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return GRUB_ERR_NONE; + + fail: + grub_free (data); +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + return grub_errno; +} + +/* Return the label of the device DEVICE in LABEL. The label is + returned in a grub_malloc'ed buffer and should be freed by the + caller. */ +static grub_err_t +grub_reiserfs_label (grub_device_t device, char **label) +{ + *label = grub_malloc (REISERFS_MAX_LABEL_LENGTH); + if (*label) + { + grub_disk_read (device->disk, + REISERFS_SUPER_BLOCK_OFFSET / GRUB_DISK_SECTOR_SIZE, + REISERFS_LABEL_OFFSET, REISERFS_MAX_LABEL_LENGTH, + *label); + } + return grub_errno; +} + +static grub_err_t +grub_reiserfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_reiserfs_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_reiserfs_mount (disk); + if (data) + { + *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); + grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->superblock.uuid[0]), grub_be_to_cpu16 (data->superblock.uuid[1]), + grub_be_to_cpu16 (data->superblock.uuid[2]), grub_be_to_cpu16 (data->superblock.uuid[3]), + grub_be_to_cpu16 (data->superblock.uuid[4]), grub_be_to_cpu16 (data->superblock.uuid[5]), + grub_be_to_cpu16 (data->superblock.uuid[6]), grub_be_to_cpu16 (data->superblock.uuid[7])); + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static struct grub_fs grub_reiserfs_fs = + { + .name = "reiserfs", + .dir = grub_reiserfs_dir, + .open = grub_reiserfs_open, + .read = grub_reiserfs_read, + .close = grub_reiserfs_close, + .label = grub_reiserfs_label, + .uuid = grub_reiserfs_uuid, + .next = 0 + }; + +GRUB_MOD_INIT(reiserfs) +{ + grub_fs_register (&grub_reiserfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(reiserfs) +{ + grub_fs_unregister (&grub_reiserfs_fs); +} diff --git a/fs/sfs.c b/fs/sfs.c new file mode 100644 index 0000000..910bbf2 --- /dev/null +++ b/fs/sfs.c @@ -0,0 +1,621 @@ +/* sfs.c - Amiga Smart FileSystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* The common header for a block. */ +struct grub_sfs_bheader +{ + grub_uint8_t magic[4]; + grub_uint32_t chksum; + grub_uint32_t ipointtomyself; +} __attribute__ ((packed)); + +/* The sfs rootblock. */ +struct grub_sfs_rblock +{ + struct grub_sfs_bheader header; + grub_uint32_t version; + grub_uint8_t unused1[36]; + grub_uint32_t blocksize; + grub_uint8_t unused2[40]; + grub_uint8_t unused3[8]; + grub_uint32_t rootobject; + grub_uint32_t btree; +} __attribute__ ((packed)); + +/* A SFS object container. */ +struct grub_sfs_obj +{ + grub_uint8_t unused1[4]; + grub_uint32_t nodeid; + grub_uint8_t unused2[4]; + union + { + struct + { + grub_uint32_t first_block; + grub_uint32_t size; + } file __attribute__ ((packed)); + struct + { + grub_uint32_t hashtable; + grub_uint32_t dir_objc; + } dir __attribute__ ((packed)); + } file_dir; + grub_uint8_t unused3[4]; + grub_uint8_t type; + grub_uint8_t filename[1]; + grub_uint8_t comment[1]; +} __attribute__ ((packed)); + +#define GRUB_SFS_TYPE_DELETED 32 +#define GRUB_SFS_TYPE_SYMLINK 64 +#define GRUB_SFS_TYPE_DIR 128 + +/* A SFS object container. */ +struct grub_sfs_objc +{ + struct grub_sfs_bheader header; + grub_uint32_t parent; + grub_uint32_t next; + grub_uint32_t prev; + /* The amount of objects depends on the blocksize. */ + struct grub_sfs_obj objects[1]; +} __attribute__ ((packed)); + +struct grub_sfs_btree_node +{ + grub_uint32_t key; + grub_uint32_t data; +} __attribute__ ((packed)); + +struct grub_sfs_btree_extent +{ + grub_uint32_t key; + grub_uint32_t next; + grub_uint32_t prev; + grub_uint16_t size; +} __attribute__ ((packed)); + +struct grub_sfs_btree +{ + struct grub_sfs_bheader header; + grub_uint16_t nodes; + grub_uint8_t leaf; + grub_uint8_t nodesize; + /* Normally this can be kind of node, but just extents are + supported. */ + struct grub_sfs_btree_node node[1]; +} __attribute__ ((packed)); + + + +struct grub_fshelp_node +{ + struct grub_sfs_data *data; + int block; + int size; +}; + +/* Information about a "mounted" sfs filesystem. */ +struct grub_sfs_data +{ + struct grub_sfs_rblock rblock; + struct grub_fshelp_node diropen; + grub_disk_t disk; + + /* Blocksize in sectors. */ + unsigned int blocksize; + + /* Label of the filesystem. */ + char *label; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +/* Lookup the extent starting with BLOCK in the filesystem described + by DATA. Return the extent size in SIZE and the following extent + in NEXTEXT. */ +static grub_err_t +grub_sfs_read_extent (struct grub_sfs_data *data, unsigned int block, + int *size, int *nextext) +{ + char *treeblock; + struct grub_sfs_btree *tree; + int i; + int next; + int prev; + + treeblock = grub_malloc (data->blocksize); + if (!block) + return 0; + + next = grub_be_to_cpu32 (data->rblock.btree); + tree = (struct grub_sfs_btree *) treeblock; + + /* Handle this level in the btree. */ + do + { + prev = 0; + + grub_disk_read (data->disk, next, 0, data->blocksize, treeblock); + if (grub_errno) + { + grub_free (treeblock); + return grub_errno; + } + + for (i = 0; i < grub_be_to_cpu16 (tree->nodes); i++) + { + +#define EXTNODE(tree, index) \ + ((struct grub_sfs_btree_node *) (((char *) &(tree)->node[0]) \ + + (index) * (tree)->nodesize)) + + /* Follow the tree down to the leaf level. */ + if ((grub_be_to_cpu32 (EXTNODE(tree, i)->key) >= block) + && !tree->leaf) + { + next = grub_be_to_cpu32 (EXTNODE (tree, i - 1)->data); + break; + } + + /* In case the last node is reached just use that one, it is + the right match. */ + if (i + 1 == grub_be_to_cpu16 (tree->nodes) && !tree->leaf) + { + next = grub_be_to_cpu32 (EXTNODE (tree, i)->data); + break; + } + + /* If the leaf level is reached, just find the correct extent. */ + if (grub_be_to_cpu32 (EXTNODE (tree, i)->key) == block && tree->leaf) + { + struct grub_sfs_btree_extent *extent; + extent = (struct grub_sfs_btree_extent *) EXTNODE (tree, i); + + /* We found a correct leaf. */ + *size = grub_be_to_cpu16 (extent->size); + *nextext = grub_be_to_cpu32 (extent->next); + + grub_free (treeblock); + return 0; + } + +#undef EXTNODE + + } + } while (!tree->leaf); + + grub_free (treeblock); + + return grub_error (GRUB_ERR_FILE_READ_ERROR, "SFS extent not found"); +} + +static grub_disk_addr_t +grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + int blk = node->block; + int size = 0; + int next = 0; + + while (blk) + { + grub_err_t err; + + /* In case of the first block we don't have to lookup the + extent, the minimum size is always 1. */ + if (fileblock == 0) + return blk; + + err = grub_sfs_read_extent (node->data, blk, &size, &next); + if (err) + return 0; + + if (fileblock < (unsigned int) size) + return fileblock + blk; + + fileblock -= size; + + blk = next; + } + + grub_error (GRUB_ERR_FILE_READ_ERROR, + "reading a SFS block outside the extent"); + + return 0; +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_sfs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_sfs_read_block, + node->size, 0); +} + + +static struct grub_sfs_data * +grub_sfs_mount (grub_disk_t disk) +{ + struct grub_sfs_data *data; + struct grub_sfs_objc *rootobjc; + char *rootobjc_data = 0; + unsigned int blk; + + data = grub_malloc (sizeof (*data)); + if (!data) + return 0; + + /* Read the rootblock. */ + grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock), + (char *) &data->rblock); + if (grub_errno) + goto fail; + + /* Make sure this is a sfs filesystem. */ + if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4)) + { + grub_error (GRUB_ERR_BAD_FS, "not a sfs filesystem"); + goto fail; + } + + data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize); + rootobjc_data = grub_malloc (data->blocksize); + if (! rootobjc_data) + goto fail; + + /* Read the root object container. */ + grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0, + data->blocksize, rootobjc_data); + if (grub_errno) + goto fail; + + rootobjc = (struct grub_sfs_objc *) rootobjc_data; + + blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc); + data->diropen.size = 0; + data->diropen.block = blk; + data->diropen.data = data; + data->disk = disk; + data->label = grub_strdup ((char *) (rootobjc->objects[0].filename)); + + return data; + + fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an sfs filesystem"); + + grub_free (data); + grub_free (rootobjc_data); + return 0; +} + + +static char * +grub_sfs_read_symlink (grub_fshelp_node_t node) +{ + struct grub_sfs_data *data = node->data; + char *symlink; + char *block; + + block = grub_malloc (data->blocksize); + if (!block) + return 0; + + grub_disk_read (data->disk, node->block, 0, data->blocksize, block); + if (grub_errno) + { + grub_free (block); + return 0; + } + + /* This is just a wild guess, but it always worked for me. How the + SLNK block looks like is not documented in the SFS docs. */ + symlink = grub_strdup (&block[24]); + grub_free (block); + if (!symlink) + return 0; + + return symlink; +} + +static int +grub_sfs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + struct grub_fshelp_node *node = 0; + struct grub_sfs_data *data = dir->data; + char *objc_data; + struct grub_sfs_objc *objc; + unsigned int next = dir->block; + int pos; + + auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, + int size, int type); + + int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, int block, + int size, int type) + { + node = grub_malloc (sizeof (*node)); + if (!node) + return 1; + + node->data = data; + node->size = size; + node->block = block; + + return hook (name, type, node); + } + + objc_data = grub_malloc (data->blocksize); + if (!objc_data) + goto fail; + + /* The Object container can consist of multiple blocks, iterate over + every block. */ + while (next) + { + grub_disk_read (data->disk, next, 0, data->blocksize, objc_data); + if (grub_errno) + goto fail; + + objc = (struct grub_sfs_objc *) objc_data; + + pos = (char *) &objc->objects[0] - (char *) objc; + + /* Iterate over all entries in this block. */ + while (pos + sizeof (struct grub_sfs_obj) < data->blocksize) + { + struct grub_sfs_obj *obj; + obj = (struct grub_sfs_obj *) ((char *) objc + pos); + char *filename = (char *) (obj->filename); + int len; + enum grub_fshelp_filetype type; + unsigned int block; + + /* The filename and comment dynamically increase the size of + the object. */ + len = grub_strlen (filename); + len += grub_strlen (filename + len + 1); + + pos += sizeof (*obj) + len; + /* Round up to a multiple of two bytes. */ + pos = ((pos + 1) >> 1) << 1; + + if (grub_strlen (filename) == 0) + continue; + + /* First check if the file was not deleted. */ + if (obj->type & GRUB_SFS_TYPE_DELETED) + continue; + else if (obj->type & GRUB_SFS_TYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (obj->type & GRUB_SFS_TYPE_DIR) + type = GRUB_FSHELP_DIR; + else + type = GRUB_FSHELP_REG; + + if (type == GRUB_FSHELP_DIR) + block = grub_be_to_cpu32 (obj->file_dir.dir.dir_objc); + else + block = grub_be_to_cpu32 (obj->file_dir.file.first_block); + + if (grub_sfs_create_node (filename, block, + grub_be_to_cpu32 (obj->file_dir.file.size), + type)) + { + grub_free (objc_data); + return 1; + } + } + + next = grub_be_to_cpu32 (objc->next); + } + + fail: + grub_free (objc_data); + return 0; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_sfs_open (struct grub_file *file, const char *name) +{ + struct grub_sfs_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_sfs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir, + grub_sfs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + file->size = fdiro->size; + data->diropen = *fdiro; + grub_free (fdiro); + + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (data && fdiro != &data->diropen) + grub_free (fdiro); + if (data) + grub_free (data->label); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_sfs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_sfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_sfs_data *data = (struct grub_sfs_data *) file->data; + + int size = grub_sfs_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); + + return size; +} + + +static grub_err_t +grub_sfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_sfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_sfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_sfs_iterate_dir, + grub_sfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_sfs_iterate_dir (fdiro, iterate); + + fail: + if (data && fdiro != &data->diropen) + grub_free (fdiro); + if (data) + grub_free (data->label); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_err_t +grub_sfs_label (grub_device_t device, char **label) +{ + struct grub_sfs_data *data; + grub_disk_t disk = device->disk; + + data = grub_sfs_mount (disk); + if (data) + *label = data->label; + + grub_free (data); + + return grub_errno; +} + + +static struct grub_fs grub_sfs_fs = + { + .name = "sfs", + .dir = grub_sfs_dir, + .open = grub_sfs_open, + .read = grub_sfs_read, + .close = grub_sfs_close, + .label = grub_sfs_label, + .next = 0 + }; + +GRUB_MOD_INIT(sfs) +{ + grub_fs_register (&grub_sfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(sfs) +{ + grub_fs_unregister (&grub_sfs_fs); +} diff --git a/fs/tar.c b/fs/tar.c new file mode 100644 index 0000000..6ab62bc --- /dev/null +++ b/fs/tar.c @@ -0,0 +1,2 @@ +#define MODE_USTAR 1 +#include "cpio.c" diff --git a/fs/udf.c b/fs/udf.c new file mode 100644 index 0000000..072e44f --- /dev/null +++ b/fs/udf.c @@ -0,0 +1,929 @@ +/* udf.c - Universal Disk Format filesystem. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_UDF_MAX_PDS 2 +#define GRUB_UDF_MAX_PMS 6 + +#define U16 grub_le_to_cpu16 +#define U32 grub_le_to_cpu32 +#define U64 grub_le_to_cpu64 + +#define GRUB_UDF_LOG2_BLKSZ 2 +#define GRUB_UDF_BLKSZ 2048 + +#define GRUB_UDF_TAG_IDENT_PVD 0x0001 +#define GRUB_UDF_TAG_IDENT_AVDP 0x0002 +#define GRUB_UDF_TAG_IDENT_VDP 0x0003 +#define GRUB_UDF_TAG_IDENT_IUVD 0x0004 +#define GRUB_UDF_TAG_IDENT_PD 0x0005 +#define GRUB_UDF_TAG_IDENT_LVD 0x0006 +#define GRUB_UDF_TAG_IDENT_USD 0x0007 +#define GRUB_UDF_TAG_IDENT_TD 0x0008 +#define GRUB_UDF_TAG_IDENT_LVID 0x0009 + +#define GRUB_UDF_TAG_IDENT_FSD 0x0100 +#define GRUB_UDF_TAG_IDENT_FID 0x0101 +#define GRUB_UDF_TAG_IDENT_AED 0x0102 +#define GRUB_UDF_TAG_IDENT_IE 0x0103 +#define GRUB_UDF_TAG_IDENT_TE 0x0104 +#define GRUB_UDF_TAG_IDENT_FE 0x0105 +#define GRUB_UDF_TAG_IDENT_EAHD 0x0106 +#define GRUB_UDF_TAG_IDENT_USE 0x0107 +#define GRUB_UDF_TAG_IDENT_SBD 0x0108 +#define GRUB_UDF_TAG_IDENT_PIE 0x0109 +#define GRUB_UDF_TAG_IDENT_EFE 0x010A + +#define GRUB_UDF_ICBTAG_TYPE_UNDEF 0x00 +#define GRUB_UDF_ICBTAG_TYPE_USE 0x01 +#define GRUB_UDF_ICBTAG_TYPE_PIE 0x02 +#define GRUB_UDF_ICBTAG_TYPE_IE 0x03 +#define GRUB_UDF_ICBTAG_TYPE_DIRECTORY 0x04 +#define GRUB_UDF_ICBTAG_TYPE_REGULAR 0x05 +#define GRUB_UDF_ICBTAG_TYPE_BLOCK 0x06 +#define GRUB_UDF_ICBTAG_TYPE_CHAR 0x07 +#define GRUB_UDF_ICBTAG_TYPE_EA 0x08 +#define GRUB_UDF_ICBTAG_TYPE_FIFO 0x09 +#define GRUB_UDF_ICBTAG_TYPE_SOCKET 0x0A +#define GRUB_UDF_ICBTAG_TYPE_TE 0x0B +#define GRUB_UDF_ICBTAG_TYPE_SYMLINK 0x0C +#define GRUB_UDF_ICBTAG_TYPE_STREAMDIR 0x0D + +#define GRUB_UDF_ICBTAG_FLAG_AD_MASK 0x0007 +#define GRUB_UDF_ICBTAG_FLAG_AD_SHORT 0x0000 +#define GRUB_UDF_ICBTAG_FLAG_AD_LONG 0x0001 +#define GRUB_UDF_ICBTAG_FLAG_AD_EXT 0x0002 +#define GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB 0x0003 + +#define GRUB_UDF_EXT_NORMAL 0x00000000 +#define GRUB_UDF_EXT_NREC_ALLOC 0x40000000 +#define GRUB_UDF_EXT_NREC_NALLOC 0x80000000 +#define GRUB_UDF_EXT_MASK 0xC0000000 + +#define GRUB_UDF_FID_CHAR_HIDDEN 0x01 +#define GRUB_UDF_FID_CHAR_DIRECTORY 0x02 +#define GRUB_UDF_FID_CHAR_DELETED 0x04 +#define GRUB_UDF_FID_CHAR_PARENT 0x08 +#define GRUB_UDF_FID_CHAR_METADATA 0x10 + +#define GRUB_UDF_STD_IDENT_BEA01 "BEA01" +#define GRUB_UDF_STD_IDENT_BOOT2 "BOOT2" +#define GRUB_UDF_STD_IDENT_CD001 "CD001" +#define GRUB_UDF_STD_IDENT_CDW02 "CDW02" +#define GRUB_UDF_STD_IDENT_NSR02 "NSR02" +#define GRUB_UDF_STD_IDENT_NSR03 "NSR03" +#define GRUB_UDF_STD_IDENT_TEA01 "TEA01" + +#define GRUB_UDF_CHARSPEC_TYPE_CS0 0x00 +#define GRUB_UDF_CHARSPEC_TYPE_CS1 0x01 +#define GRUB_UDF_CHARSPEC_TYPE_CS2 0x02 +#define GRUB_UDF_CHARSPEC_TYPE_CS3 0x03 +#define GRUB_UDF_CHARSPEC_TYPE_CS4 0x04 +#define GRUB_UDF_CHARSPEC_TYPE_CS5 0x05 +#define GRUB_UDF_CHARSPEC_TYPE_CS6 0x06 +#define GRUB_UDF_CHARSPEC_TYPE_CS7 0x07 +#define GRUB_UDF_CHARSPEC_TYPE_CS8 0x08 + +#define GRUB_UDF_PARTMAP_TYPE_1 1 +#define GRUB_UDF_PARTMAP_TYPE_2 2 + +struct grub_udf_lb_addr +{ + grub_uint32_t block_num; + grub_uint16_t part_ref; +} __attribute__ ((packed)); + +struct grub_udf_short_ad +{ + grub_uint32_t length; + grub_uint32_t position; +} __attribute__ ((packed)); + +struct grub_udf_long_ad +{ + grub_uint32_t length; + struct grub_udf_lb_addr block; + grub_uint8_t imp_use[6]; +} __attribute__ ((packed)); + +struct grub_udf_extent_ad +{ + grub_uint32_t length; + grub_uint32_t start; +} __attribute__ ((packed)); + +struct grub_udf_charspec +{ + grub_uint8_t charset_type; + grub_uint8_t charset_info[63]; +} __attribute__ ((packed)); + +struct grub_udf_timestamp +{ + grub_uint16_t type_and_timezone; + grub_uint16_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; + grub_uint8_t centi_seconds; + grub_uint8_t hundreds_of_micro_seconds; + grub_uint8_t micro_seconds; +} __attribute__ ((packed)); + +struct grub_udf_regid +{ + grub_uint8_t flags; + grub_uint8_t ident[23]; + grub_uint8_t ident_suffix[8]; +} __attribute__ ((packed)); + +struct grub_udf_tag +{ + grub_uint16_t tag_ident; + grub_uint16_t desc_version; + grub_uint8_t tag_checksum; + grub_uint8_t reserved; + grub_uint16_t tag_serial_number; + grub_uint16_t desc_crc; + grub_uint16_t desc_crc_length; + grub_uint32_t tag_location; +} __attribute__ ((packed)); + +struct grub_udf_fileset +{ + struct grub_udf_tag tag; + struct grub_udf_timestamp datetime; + grub_uint16_t interchange_level; + grub_uint16_t max_interchange_level; + grub_uint32_t charset_list; + grub_uint32_t max_charset_list; + grub_uint32_t fileset_num; + grub_uint32_t fileset_desc_num; + struct grub_udf_charspec vol_charset; + grub_uint8_t vol_ident[128]; + struct grub_udf_charspec fileset_charset; + grub_uint8_t fileset_ident[32]; + grub_uint8_t copyright_file_ident[32]; + grub_uint8_t abstract_file_ident[32]; + struct grub_udf_long_ad root_icb; + struct grub_udf_regid domain_ident; + struct grub_udf_long_ad next_ext; + struct grub_udf_long_ad streamdir_icb; +} __attribute__ ((packed)); + +struct grub_udf_icbtag +{ + grub_uint32_t prior_recorded_num_direct_entries; + grub_uint16_t strategy_type; + grub_uint16_t strategy_parameter; + grub_uint16_t num_entries; + grub_uint8_t reserved; + grub_uint8_t file_type; + struct grub_udf_lb_addr parent_idb; + grub_uint16_t flags; +} __attribute__ ((packed)); + +struct grub_udf_file_ident +{ + struct grub_udf_tag tag; + grub_uint16_t version_num; + grub_uint8_t characteristics; + grub_uint8_t file_ident_length; + struct grub_udf_long_ad icb; + grub_uint16_t imp_use_length; +} __attribute__ ((packed)); + +struct grub_udf_file_entry +{ + struct grub_udf_tag tag; + struct grub_udf_icbtag icbtag; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t permissions; + grub_uint16_t link_count; + grub_uint8_t record_format; + grub_uint8_t record_display_attr; + grub_uint32_t record_length; + grub_uint64_t file_size; + grub_uint64_t blocks_recorded; + struct grub_udf_timestamp access_time; + struct grub_udf_timestamp modification_time; + struct grub_udf_timestamp attr_time; + grub_uint32_t checkpoint; + struct grub_udf_long_ad extended_attr_idb; + struct grub_udf_regid imp_ident; + grub_uint64_t unique_id; + grub_uint32_t ext_attr_length; + grub_uint32_t alloc_descs_length; + grub_uint8_t ext_attr[1872]; +} __attribute__ ((packed)); + +struct grub_udf_extended_file_entry +{ + struct grub_udf_tag tag; + struct grub_udf_icbtag icbtag; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t permissions; + grub_uint16_t link_count; + grub_uint8_t record_format; + grub_uint8_t record_display_attr; + grub_uint32_t record_length; + grub_uint64_t file_size; + grub_uint64_t object_size; + grub_uint64_t blocks_recorded; + struct grub_udf_timestamp access_time; + struct grub_udf_timestamp modification_time; + struct grub_udf_timestamp create_time; + struct grub_udf_timestamp attr_time; + grub_uint32_t checkpoint; + grub_uint32_t reserved; + struct grub_udf_long_ad extended_attr_icb; + struct grub_udf_long_ad streamdir_icb; + struct grub_udf_regid imp_ident; + grub_uint64_t unique_id; + grub_uint32_t ext_attr_length; + grub_uint32_t alloc_descs_length; + grub_uint8_t ext_attr[1832]; +} __attribute__ ((packed)); + +struct grub_udf_vrs +{ + grub_uint8_t type; + grub_uint8_t magic[5]; + grub_uint8_t version; +} __attribute__ ((packed)); + +struct grub_udf_avdp +{ + struct grub_udf_tag tag; + struct grub_udf_extent_ad vds; +} __attribute__ ((packed)); + +struct grub_udf_pd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + grub_uint16_t flags; + grub_uint16_t part_num; + struct grub_udf_regid contents; + grub_uint8_t contents_use[128]; + grub_uint32_t access_type; + grub_uint32_t start; + grub_uint32_t length; +} __attribute__ ((packed)); + +struct grub_udf_partmap +{ + grub_uint8_t type; + grub_uint8_t length; + union + { + struct + { + grub_uint16_t seq_num; + grub_uint16_t part_num; + } type1; + + struct + { + grub_uint8_t ident[62]; + } type2; + }; +}; + +struct grub_udf_lvd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + struct grub_udf_charspec charset; + grub_uint8_t ident[128]; + grub_uint32_t bsize; + struct grub_udf_regid domain_ident; + struct grub_udf_long_ad root_fileset; + grub_uint32_t map_table_length; + grub_uint32_t num_part_maps; + struct grub_udf_regid imp_ident; + grub_uint8_t imp_use[128]; + struct grub_udf_extent_ad integrity_seq_ext; + grub_uint8_t part_maps[1608]; +} __attribute__ ((packed)); + +struct grub_udf_data +{ + grub_disk_t disk; + struct grub_udf_lvd lvd; + struct grub_udf_pd pds[GRUB_UDF_MAX_PDS]; + struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS]; + struct grub_udf_long_ad root_icb; + int npd, npm; +}; + +struct grub_fshelp_node +{ + struct grub_udf_data *data; + union + { + struct grub_udf_file_entry fe; + struct grub_udf_extended_file_entry efe; + }; + int part_ref; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +static grub_uint32_t +grub_udf_get_block (struct grub_udf_data *data, + grub_uint16_t part_ref, grub_uint32_t block) +{ + part_ref = U16 (part_ref); + + if (part_ref >= data->npm) + { + grub_error (GRUB_ERR_BAD_FS, "invalid part ref"); + return 0; + } + + return (U32 (data->pds[data->pms[part_ref]->type1.part_num].start) + + U32 (block)); +} + +static grub_err_t +grub_udf_read_icb (struct grub_udf_data *data, + struct grub_udf_long_ad *icb, + struct grub_fshelp_node *node) +{ + grub_uint32_t block; + + block = grub_udf_get_block (data, + icb->block.part_ref, + icb->block.block_num); + + if (grub_errno) + return grub_errno; + + if (grub_disk_read (data->disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_file_entry), + (char *) &node->fe)) + return grub_errno; + + if ((U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FE) && + (U16 (node->fe.tag.tag_ident) != GRUB_UDF_TAG_IDENT_EFE)) + return grub_error (GRUB_ERR_BAD_FS, "invalid fe/efe descriptor"); + + node->part_ref = icb->block.part_ref; + node->data = data; + return 0; +} + +static grub_disk_addr_t +grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + char *ptr; + int len; + + if (U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) + { + ptr = (char *) &node->fe.ext_attr[0] + U32 (node->fe.ext_attr_length); + len = U32 (node->fe.alloc_descs_length); + } + else + { + ptr = (char *) &node->efe.ext_attr[0] + U32 (node->efe.ext_attr_length); + len = U32 (node->efe.alloc_descs_length); + } + + if ((U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) + == GRUB_UDF_ICBTAG_FLAG_AD_SHORT) + { + struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; + + len /= sizeof (struct grub_udf_short_ad); + while (len > 0) + { + if (fileblock < U32 (ad->length)) + return ((U32 (ad->position) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, + node->part_ref, + ad->position) + + fileblock)); + + fileblock -= U32 (ad->length); + ad++; + len--; + } + } + else + { + struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; + + len /= sizeof (struct grub_udf_long_ad); + while (len > 0) + { + if (fileblock < U32 (ad->length)) + return ((U32 (ad->block.block_num) & GRUB_UDF_EXT_MASK) ? 0 : + (grub_udf_get_block (node->data, + ad->block.part_ref, + ad->block.block_num) + + fileblock)); + + fileblock -= U32 (ad->length); + ad++; + len--; + } + } + + return 0; +} + +static grub_ssize_t +grub_udf_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR + (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + switch (U16 (node->fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) + { + case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB: + { + char *ptr; + + ptr = ((U16 (node->fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ? + ((char *) &node->fe.ext_attr[0] + + U32 (node->fe.ext_attr_length)) : + ((char *) &node->efe.ext_attr[0] + + U32 (node->efe.ext_attr_length))); + + grub_memcpy (buf, ptr + pos, len); + + return len; + } + + case GRUB_UDF_ICBTAG_FLAG_AD_EXT: + grub_error (GRUB_ERR_BAD_FS, "invalid extent type"); + return 0; + } + + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_udf_read_block, + U64 (node->fe.file_size), + GRUB_UDF_LOG2_BLKSZ); +} + +static int sblocklist[] = { 256, 512, 0 }; + +static struct grub_udf_data * +grub_udf_mount (grub_disk_t disk) +{ + struct grub_udf_data *data = 0; + struct grub_udf_fileset root_fs; + int *sblklist = sblocklist; + grub_uint32_t block; + int i; + + data = grub_malloc (sizeof (struct grub_udf_data)); + if (!data) + return 0; + + data->disk = disk; + + /* Search for Volume Recognition Sequence (VRS). */ + for (block = 16;; block++) + { + struct grub_udf_vrs vrs; + + if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_vrs), (char *) &vrs)) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + if ((!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR03, 5)) || + (!grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_NSR02, 5))) + break; + + if ((grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BEA01, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_BOOT2, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CD001, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) && + (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5))) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + } + + /* Search for Anchor Volume Descriptor Pointer (AVDP). */ + while (1) + { + struct grub_udf_avdp avdp; + + if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_avdp), (char *) &avdp)) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + if (U16 (avdp.tag.tag_ident) == GRUB_UDF_TAG_IDENT_AVDP) + { + block = U32 (avdp.vds.start); + break; + } + + sblklist++; + if (*sblklist == 0) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + } + + data->npd = data->npm = 0; + /* Locate Partiton Descriptor (PD) and Logical Volume Descriptor (LVD). */ + while (1) + { + struct grub_udf_tag tag; + + if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_tag), (char *) &tag)) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + tag.tag_ident = U16 (tag.tag_ident); + if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD) + { + if (data->npd >= GRUB_UDF_MAX_PDS) + { + grub_error (GRUB_ERR_BAD_FS, "too many PDs"); + goto fail; + } + + if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_pd), + (char *) &data->pds[data->npd])) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + data->npd++; + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_LVD) + { + int k; + + struct grub_udf_partmap *ppm; + + if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_lvd), + (char *) &data->lvd)) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + if (data->npm + U32 (data->lvd.num_part_maps) > GRUB_UDF_MAX_PMS) + { + grub_error (GRUB_ERR_BAD_FS, "too many partition maps"); + goto fail; + } + + ppm = (struct grub_udf_partmap *) &data->lvd.part_maps; + for (k = U32 (data->lvd.num_part_maps); k > 0; k--) + { + if (ppm->type != GRUB_UDF_PARTMAP_TYPE_1) + { + grub_error (GRUB_ERR_BAD_FS, "partmap type not supported"); + goto fail; + } + + data->pms[data->npm++] = ppm; + ppm = (struct grub_udf_partmap *) ((char *) ppm + + U32 (ppm->length)); + } + } + else if (tag.tag_ident > GRUB_UDF_TAG_IDENT_TD) + { + grub_error (GRUB_ERR_BAD_FS, "invalid tag ident"); + goto fail; + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_TD) + break; + + block++; + } + + for (i = 0; i < data->npm; i++) + { + int j; + + for (j = 0; j < data->npd; j++) + if (data->pms[i]->type1.part_num == data->pds[j].part_num) + { + data->pms[i]->type1.part_num = j; + break; + } + + if (j == data->npd) + { + grub_error (GRUB_ERR_BAD_FS, "can\'t find PD"); + goto fail; + } + } + + block = grub_udf_get_block (data, + data->lvd.root_fileset.block.part_ref, + data->lvd.root_fileset.block.block_num); + + if (grub_errno) + goto fail; + + if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, + sizeof (struct grub_udf_fileset), (char *) &root_fs)) + { + grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + goto fail; + } + + if (U16 (root_fs.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FSD) + { + grub_error (GRUB_ERR_BAD_FS, "invalid fileset descriptor"); + goto fail; + } + + data->root_icb = root_fs.root_icb; + + return data; + +fail: + grub_free (data); + return 0; +} + +static int +grub_udf_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + grub_fshelp_node_t child; + struct grub_udf_file_ident dirent; + grub_uint32_t offset = 0; + + child = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!child) + return 0; + + /* The current directory is not stored. */ + grub_memcpy ((char *) child, (char *) dir, + sizeof (struct grub_fshelp_node)); + + if (hook (".", GRUB_FSHELP_DIR, child)) + return 1; + + while (offset < U64 (dir->fe.file_size)) + { + if (grub_udf_read_file (dir, 0, offset, sizeof (dirent), + (char *) &dirent) != sizeof (dirent)) + return 0; + + if (U16 (dirent.tag.tag_ident) != GRUB_UDF_TAG_IDENT_FID) + { + grub_error (GRUB_ERR_BAD_FS, "invalid fid tag"); + return 0; + } + + child = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!child) + return 0; + + if (grub_udf_read_icb (dir->data, &dirent.icb, child)) + return 0; + + offset += sizeof (dirent) + U16 (dirent.imp_use_length); + if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) + { + /* This is the parent directory. */ + if (hook ("..", GRUB_FSHELP_DIR, child)) + return 1; + } + else + { + enum grub_fshelp_filetype type; + char filename[dirent.file_ident_length + 1]; + + type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? + (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); + + if ((grub_udf_read_file (dir, 0, offset, + dirent.file_ident_length, filename)) + != dirent.file_ident_length) + return 0; + + filename[dirent.file_ident_length] = 0; + if (hook (&filename[1], type, child)) + return 1; + } + + /* Align to dword boundary. */ + offset = (offset + dirent.file_ident_length + 3) & (~3); + } + + return 0; +} + +static grub_err_t +grub_udf_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_udf_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_udf_mount (device->disk); + if (!data) + goto fail; + + if (grub_udf_read_icb (data, &data->root_icb, &rootnode)) + goto fail; + + if (grub_fshelp_find_file (path, &rootnode, + &foundnode, + grub_udf_iterate_dir, 0, GRUB_FSHELP_DIR)) + goto fail; + + grub_udf_iterate_dir (foundnode, iterate); + + if (foundnode != &rootnode) + grub_free (foundnode); + +fail: + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + +static grub_err_t +grub_udf_open (struct grub_file *file, const char *name) +{ + struct grub_udf_data *data; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_udf_mount (file->device->disk); + if (!data) + goto fail; + + if (grub_udf_read_icb (data, &data->root_icb, &rootnode)) + goto fail; + + if (grub_fshelp_find_file (name, &rootnode, + &foundnode, + grub_udf_iterate_dir, 0, GRUB_FSHELP_REG)) + goto fail; + + file->data = foundnode; + file->offset = 0; + file->size = U64 (foundnode->fe.file_size); + + return 0; + +fail: +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static grub_ssize_t +grub_udf_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; + + return grub_udf_read_file (node, file->read_hook, file->offset, len, buf); +} + +static grub_err_t +grub_udf_close (grub_file_t file) +{ + if (file->data) + { + struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; + + grub_free (node->data); + grub_free (node); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_udf_label (grub_device_t device, char **label) +{ + struct grub_udf_data *data; + data = grub_udf_mount (device->disk); + + if (data) + { + *label = grub_strdup ((char *) &data->lvd.ident[1]); + grub_free (data); + } + else + *label = 0; + + return grub_errno; +} + +static struct grub_fs grub_udf_fs = { + .name = "udf", + .dir = grub_udf_dir, + .open = grub_udf_open, + .read = grub_udf_read, + .close = grub_udf_close, + .label = grub_udf_label, + .next = 0 +}; + +GRUB_MOD_INIT (udf) +{ + grub_fs_register (&grub_udf_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI (udf) +{ + grub_fs_unregister (&grub_udf_fs); +} diff --git a/fs/ufs.c b/fs/ufs.c new file mode 100644 index 0000000..1f333b0 --- /dev/null +++ b/fs/ufs.c @@ -0,0 +1,715 @@ +/* ufs.c - Unix File System */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + + +#define GRUB_UFS_MAGIC 0x11954 +#define GRUB_UFS2_MAGIC 0x19540119 +#define GRUB_UFS_INODE 2 +#define GRUB_UFS_FILETYPE_DIR 4 +#define GRUB_UFS_FILETYPE_LNK 10 +#define GRUB_UFS_MAX_SYMLNK_CNT 8 + +#define GRUB_UFS_DIRBLKS 12 +#define GRUB_UFS_INDIRBLKS 3 + +#define GRUB_UFS_ATTR_DIR 040000 + +#define GRUB_UFS_VOLNAME_LEN 32 + +/* Calculate in which group the inode can be found. */ +#define inode_group(inode,sblock) () + +#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize)) + +#define INODE(data,field) (data->ufs_type == UFS1 ? \ + data->inode. field : data->inode2. field) +#define INODE_ENDIAN(data,field,bits1,bits2) (data->ufs_type == UFS1 ? \ + grub_le_to_cpu##bits1 (data->inode.field) : \ + grub_le_to_cpu##bits2 (data->inode2.field)) +#define INODE_SIZE(data) INODE_ENDIAN (data,size,32,64) +#define INODE_MODE(data) INODE_ENDIAN (data,mode,16,16) +#define INODE_BLKSZ(data) (data->ufs_type == UFS1 ? 4 : 8) +#define INODE_DIRBLOCKS(data,blk) INODE_ENDIAN \ + (data,blocks.dir_blocks[blk],32,64) +#define INODE_INDIRBLOCKS(data,blk) INODE_ENDIAN \ + (data,blocks.indir_blocks[blk],32,64) + +/* The blocks on which the superblock can be found. */ +static int sblocklist[] = { 128, 16, 0, 512, -1 }; + +struct grub_ufs_sblock +{ + grub_uint8_t unused[16]; + /* The offset of the inodes in the cylinder group. */ + grub_uint32_t inoblk_offs; + + grub_uint8_t unused2[4]; + + /* The start of the cylinder group. */ + grub_uint32_t cylg_offset; + + grub_uint8_t unused3[20]; + + /* The size of a block in bytes. */ + grub_int32_t bsize; + grub_uint8_t unused4[48]; + + /* The size of filesystem blocks to disk blocks. */ + grub_uint32_t log2_blksz; + grub_uint8_t unused5[80]; + + /* Inodes stored per cylinder group. */ + grub_uint32_t ino_per_group; + + /* The frags per cylinder group. */ + grub_uint32_t frags_per_group; + + grub_uint8_t unused7[488]; + + /* Volume name for UFS2. */ + grub_uint8_t volume_name[GRUB_UFS_VOLNAME_LEN]; + + grub_uint8_t unused8[660]; + + /* Magic value to check if this is really a UFS filesystem. */ + grub_uint32_t magic; +}; + +/* UFS inode. */ +struct grub_ufs_inode +{ + grub_uint16_t mode; + grub_uint16_t nlinks; + grub_uint16_t uid; + grub_uint16_t gid; + grub_int64_t size; + grub_uint64_t atime; + grub_uint64_t mtime; + grub_uint64_t ctime; + union + { + struct + { + grub_uint32_t dir_blocks[GRUB_UFS_DIRBLKS]; + grub_uint32_t indir_blocks[GRUB_UFS_INDIRBLKS]; + } blocks; + grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 4]; + }; + grub_uint32_t flags; + grub_uint32_t nblocks; + grub_uint32_t gen; + grub_uint32_t unused; + grub_uint8_t pad[12]; +}; + +/* UFS inode. */ +struct grub_ufs2_inode +{ + grub_uint16_t mode; + grub_uint16_t nlinks; + grub_uint32_t uid; + grub_uint32_t gid; + grub_uint32_t blocksize; + grub_int64_t size; + grub_int64_t nblocks; + grub_uint64_t atime; + grub_uint64_t mtime; + grub_uint64_t ctime; + grub_uint64_t create_time; + grub_uint32_t atime_sec; + grub_uint32_t mtime_sec; + grub_uint32_t ctime_sec; + grub_uint32_t create_time_sec; + grub_uint32_t gen; + grub_uint32_t kernel_flags; + grub_uint32_t flags; + grub_uint32_t extsz; + grub_uint64_t ext[2]; + union + { + struct + { + grub_uint64_t dir_blocks[GRUB_UFS_DIRBLKS]; + grub_uint64_t indir_blocks[GRUB_UFS_INDIRBLKS]; + } blocks; + grub_uint8_t symlink[(GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS) * 8]; + }; + + grub_uint8_t unused[24]; +}; + +/* Directory entry. */ +struct grub_ufs_dirent +{ + grub_uint32_t ino; + grub_uint16_t direntlen; + grub_uint8_t filetype; + grub_uint8_t namelen; +}; + +/* Information about a "mounted" ufs filesystem. */ +struct grub_ufs_data +{ + struct grub_ufs_sblock sblock; + grub_disk_t disk; + union + { + struct grub_ufs_inode inode; + struct grub_ufs2_inode inode2; + }; + enum + { + UFS1, + UFS2, + UNKNOWN + } ufs_type; + int ino; + int linknest; +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +/* Forward declaration. */ +static grub_err_t grub_ufs_find_file (struct grub_ufs_data *data, + const char *path); + + +static int +grub_ufs_get_file_block (struct grub_ufs_data *data, unsigned int blk) +{ + struct grub_ufs_sblock *sblock = &data->sblock; + unsigned int indirsz; + int log2_blksz; + + /* Direct. */ + if (blk < GRUB_UFS_DIRBLKS) + return INODE_DIRBLOCKS (data, blk); + + log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz); + + blk -= GRUB_UFS_DIRBLKS; + + indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ (data); + /* Single indirect block. */ + if (blk < indirsz) + { + grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2]; + grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 0) << log2_blksz, + 0, sizeof (indir), (char *) indir); + return (data->ufs_type == UFS1) ? indir[blk] : indir[blk << 1]; + } + blk -= indirsz; + + /* Double indirect block. */ + if (blk < UFS_BLKSZ (sblock) / indirsz) + { + grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2]; + + grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz, + 0, sizeof (indir), (char *) indir); + grub_disk_read (data->disk, + (data->ufs_type == UFS1) ? + indir[blk / indirsz] : indir [(blk / indirsz) << 1], + 0, sizeof (indir), (char *) indir); + + return (data->ufs_type == UFS1) ? + indir[blk % indirsz] : indir[(blk % indirsz) << 1]; + } + + + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "ufs does not support triple indirect blocks"); + return 0; +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_ufs_read_file (struct grub_ufs_data *data, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + struct grub_ufs_sblock *sblock = &data->sblock; + int i; + int blockcnt; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > INODE_SIZE (data)) + len = INODE_SIZE (data); + + blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock); + + for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++) + { + int blknr; + int blockoff = pos % UFS_BLKSZ (sblock); + int blockend = UFS_BLKSZ (sblock); + + int skipfirst = 0; + + blknr = grub_ufs_get_file_block (data, i); + if (grub_errno) + return -1; + + /* Last block. */ + if (i == blockcnt - 1) + { + blockend = (len + pos) % UFS_BLKSZ (sblock); + + if (!blockend) + blockend = UFS_BLKSZ (sblock); + } + + /* First block. */ + if (i == (pos / (int) UFS_BLKSZ (sblock))) + { + skipfirst = blockoff; + blockend -= skipfirst; + } + + /* XXX: If the block number is 0 this block is not stored on + disk but is zero filled instead. */ + if (blknr) + { + data->disk->read_hook = read_hook; + grub_disk_read (data->disk, + blknr << grub_le_to_cpu32 (data->sblock.log2_blksz), + skipfirst, blockend, buf); + data->disk->read_hook = 0; + if (grub_errno) + return -1; + } + else + grub_memset (buf, UFS_BLKSZ (sblock) - skipfirst, 0); + + buf += UFS_BLKSZ (sblock) - skipfirst; + } + + return len; +} + + +/* Read inode INO from the mounted filesystem described by DATA. This + inode is used by default now. */ +static grub_err_t +grub_ufs_read_inode (struct grub_ufs_data *data, int ino) +{ + struct grub_ufs_sblock *sblock = &data->sblock; + + /* Determine the group the inode is in. */ + int group = ino / grub_le_to_cpu32 (sblock->ino_per_group); + + /* Determine the inode within the group. */ + int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group); + + /* The first block of the group. */ + int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group)); + + if (data->ufs_type == UFS1) + { + struct grub_ufs_inode *inode = &data->inode; + + grub_disk_read (data->disk, + (((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk) + << grub_le_to_cpu32 (data->sblock.log2_blksz))) + + grpino / 4, + (grpino % 4) * sizeof (struct grub_ufs_inode), + sizeof (struct grub_ufs_inode), + (char *) inode); + } + else + { + struct grub_ufs2_inode *inode = &data->inode2; + + grub_disk_read (data->disk, + (((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk) + << grub_le_to_cpu32 (data->sblock.log2_blksz))) + + grpino / 2, + (grpino % 2) * sizeof (struct grub_ufs2_inode), + sizeof (struct grub_ufs2_inode), + (char *) inode); + } + + data->ino = ino; + return grub_errno; +} + + +/* Lookup the symlink the current inode points to. INO is the inode + number of the directory the symlink is relative to. */ +static grub_err_t +grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) +{ + char symlink[INODE_SIZE (data)]; + + if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT) + return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks"); + + if (INODE_SIZE (data) < (GRUB_UFS_DIRBLKS + GRUB_UFS_INDIRBLKS + * INODE_BLKSZ (data))) + grub_strcpy (symlink, (char *) INODE (data, symlink)); + else + { + grub_disk_read (data->disk, + (INODE_DIRBLOCKS (data, 0) + << grub_le_to_cpu32 (data->sblock.log2_blksz)), + 0, INODE_SIZE (data), symlink); + symlink[INODE_SIZE (data)] = '\0'; + } + + /* The symlink is an absolute path, go back to the root inode. */ + if (symlink[0] == '/') + ino = GRUB_UFS_INODE; + + /* Now load in the old inode. */ + if (grub_ufs_read_inode (data, ino)) + return grub_errno; + + grub_ufs_find_file (data, symlink); + if (grub_errno) + grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + + return grub_errno; +} + + +/* Find the file with the pathname PATH on the filesystem described by + DATA. */ +static grub_err_t +grub_ufs_find_file (struct grub_ufs_data *data, const char *path) +{ + char fpath[grub_strlen (path) + 1]; + char *name = fpath; + char *next; + unsigned int pos = 0; + int dirino; + + grub_strcpy (fpath, path); + + /* Skip the first slash. */ + if (name[0] == '/') + { + name++; + if (!*name) + return 0; + } + + /* Extract the actual part from the pathname. */ + next = grub_strchr (name, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + do + { + struct grub_ufs_dirent dirent; + + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; + + if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), + (char *) &dirent) < 0) + return grub_errno; + + { + char filename[dirent.namelen + 1]; + + if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), + dirent.namelen, filename) < 0) + return grub_errno; + + filename[dirent.namelen] = '\0'; + + if (!grub_strcmp (name, filename)) + { + dirino = data->ino; + grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino)); + + if (dirent.filetype == GRUB_UFS_FILETYPE_LNK) + { + grub_ufs_lookup_symlink (data, dirino); + if (grub_errno) + return grub_errno; + } + + if (!next) + return 0; + + pos = 0; + + name = next; + next = grub_strchr (name, '/'); + if (next) + { + next[0] = '\0'; + next++; + } + + if (!(dirent.filetype & GRUB_UFS_FILETYPE_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + + continue; + } + } + + pos += grub_le_to_cpu16 (dirent.direntlen); + } while (pos < INODE_SIZE (data)); + + grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + return grub_errno; +} + + +/* Mount the filesystem on the disk DISK. */ +static struct grub_ufs_data * +grub_ufs_mount (grub_disk_t disk) +{ + struct grub_ufs_data *data; + int *sblklist = sblocklist; + + data = grub_malloc (sizeof (struct grub_ufs_data)); + if (!data) + return 0; + + /* Find a UFS1 or UFS2 sblock. */ + data->ufs_type = UNKNOWN; + while (*sblklist != -1) + { + grub_disk_read (disk, *sblklist, 0, sizeof (struct grub_ufs_sblock), + (char *) &data->sblock); + if (grub_errno) + goto fail; + + if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC) + { + data->ufs_type = UFS1; + break; + } + else if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS2_MAGIC) + { + data->ufs_type = UFS2; + break; + } + sblklist++; + } + if (data->ufs_type == UNKNOWN) + { + grub_error (GRUB_ERR_BAD_FS, "not an ufs filesystem"); + goto fail; + } + + data->disk = disk; + data->linknest = 0; + return data; + + fail: + grub_free (data); + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a ufs filesystem"); + + return 0; +} + + +static grub_err_t +grub_ufs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_ufs_data *data; + struct grub_ufs_sblock *sblock; + unsigned int pos = 0; + + data = grub_ufs_mount (device->disk); + if (!data) + return grub_errno; + + grub_ufs_read_inode (data, GRUB_UFS_INODE); + if (grub_errno) + return grub_errno; + + sblock = &data->sblock; + + if (!path || path[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return grub_errno; + } + + grub_ufs_find_file (data, path); + if (grub_errno) + goto fail; + + if (!(INODE_MODE (data) & GRUB_UFS_ATTR_DIR)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory"); + goto fail; + } + + while (pos < INODE_SIZE (data)) + { + struct grub_ufs_dirent dirent; + + if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), + (char *) &dirent) < 0) + break; + + { + char filename[dirent.namelen + 1]; + + if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), + dirent.namelen, filename) < 0) + break; + + filename[dirent.namelen] = '\0'; + if (hook (filename, dirent.filetype == GRUB_UFS_FILETYPE_DIR)) + break; + } + + pos += grub_le_to_cpu16 (dirent.direntlen); + } + + fail: + grub_free (data); + + return grub_errno; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_ufs_open (struct grub_file *file, const char *name) +{ + struct grub_ufs_data *data; + data = grub_ufs_mount (file->device->disk); + if (!data) + return grub_errno; + + grub_ufs_read_inode (data, 2); + if (grub_errno) + { + grub_free (data); + return grub_errno; + } + + if (!name || name[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, "bad filename"); + return grub_errno; + } + + grub_ufs_find_file (data, name); + if (grub_errno) + { + grub_free (data); + return grub_errno; + } + + file->data = data; + file->size = INODE_SIZE (data); + + return GRUB_ERR_NONE; +} + + +static grub_ssize_t +grub_ufs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_ufs_data *data = + (struct grub_ufs_data *) file->data; + + return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf); +} + + +static grub_err_t +grub_ufs_close (grub_file_t file) +{ + grub_free (file->data); + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_ufs_label (grub_device_t device, char **label) +{ + struct grub_ufs_data *data = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + *label = 0; + + data = grub_ufs_mount (device->disk); + if (data) + { + if (data->ufs_type == UFS2) + *label = grub_strdup ((char *) data->sblock.volume_name); + } + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + + +static struct grub_fs grub_ufs_fs = + { + .name = "ufs", + .dir = grub_ufs_dir, + .open = grub_ufs_open, + .read = grub_ufs_read, + .close = grub_ufs_close, + .label = grub_ufs_label, + .next = 0 + }; + +GRUB_MOD_INIT(ufs) +{ + grub_fs_register (&grub_ufs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(ufs) +{ + grub_fs_unregister (&grub_ufs_fs); +} + diff --git a/fs/xfs.c b/fs/xfs.c new file mode 100644 index 0000000..81a2771 --- /dev/null +++ b/fs/xfs.c @@ -0,0 +1,833 @@ +/* xfs.c - XFS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define XFS_INODE_EXTENTS 9 + +#define XFS_INODE_FORMAT_INO 1 +#define XFS_INODE_FORMAT_EXT 2 +#define XFS_INODE_FORMAT_BTREE 3 + + +struct grub_xfs_sblock +{ + grub_uint8_t magic[4]; + grub_uint32_t bsize; + grub_uint8_t unused1[24]; + grub_uint16_t uuid[8]; + grub_uint8_t unused2[8]; + grub_uint64_t rootino; + grub_uint8_t unused3[20]; + grub_uint32_t agsize; + grub_uint8_t unused4[20]; + grub_uint8_t label[12]; + grub_uint8_t log2_bsize; + grub_uint8_t unused5[2]; + grub_uint8_t log2_inop; + grub_uint8_t log2_agblk; + grub_uint8_t unused6[67]; + grub_uint8_t log2_dirblk; +} __attribute__ ((packed)); + +struct grub_xfs_dir_header +{ + grub_uint8_t count; + grub_uint8_t smallino; + union + { + grub_uint32_t i4; + grub_uint64_t i8; + } parent __attribute__ ((packed)); +} __attribute__ ((packed)); + +struct grub_xfs_dir_entry +{ + grub_uint8_t len; + grub_uint16_t offset; + char name[1]; + /* Inode number follows, 32 bits. */ +} __attribute__ ((packed)); + +struct grub_xfs_dir2_entry +{ + grub_uint64_t inode; + grub_uint8_t len; +} __attribute__ ((packed)); + +typedef grub_uint32_t grub_xfs_extent[4]; + +struct grub_xfs_btree_node +{ + grub_uint8_t magic[4]; + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t left; + grub_uint64_t right; + grub_uint64_t keys[1]; +} __attribute__ ((packed)); + +struct grub_xfs_btree_root +{ + grub_uint16_t level; + grub_uint16_t numrecs; + grub_uint64_t keys[1]; +} __attribute__ ((packed)); + +struct grub_xfs_inode +{ + grub_uint8_t magic[2]; + grub_uint16_t mode; + grub_uint8_t version; + grub_uint8_t format; + grub_uint8_t unused2[50]; + grub_uint64_t size; + grub_uint64_t nblocks; + grub_uint32_t extsize; + grub_uint32_t nextents; + grub_uint8_t unused3[20]; + union + { + char raw[156]; + struct dir + { + struct grub_xfs_dir_header dirhead; + struct grub_xfs_dir_entry direntry[1]; + } dir; + grub_xfs_extent extents[XFS_INODE_EXTENTS]; + struct grub_xfs_btree_root btree; + } data __attribute__ ((packed)); +} __attribute__ ((packed)); + +struct grub_xfs_dirblock_tail +{ + grub_uint32_t leaf_count; + grub_uint32_t leaf_stale; +} __attribute__ ((packed)); + +struct grub_fshelp_node +{ + struct grub_xfs_data *data; + struct grub_xfs_inode inode; + grub_uint64_t ino; + int inode_read; +}; + +struct grub_xfs_data +{ + struct grub_xfs_sblock sblock; + struct grub_xfs_inode *inode; + grub_disk_t disk; + int pos; + int bsize; + int agsize; + struct grub_fshelp_node diropen; + +}; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#define GRUB_XFS_INO_AGBITS(data) \ + ((data)->sblock.log2_agblk + (data)->sblock.log2_inop) +#define GRUB_XFS_INO_INOINAG(data, ino) \ + (grub_be_to_cpu64 (ino) & ((1 << GRUB_XFS_INO_AGBITS (data)) - 1)) +#define GRUB_XFS_INO_AG(data,ino) \ + (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data)) + +#define GRUB_XFS_FSB_TO_BLOCK(data, fsb) \ + (((fsb) >> (data)->sblock.log2_agblk) * (data)->agsize \ + + ((fsb) & ((1 << (data)->sblock.log2_agblk) - 1))) + +#define GRUB_XFS_EXTENT_OFFSET(exts,ex) \ + ((grub_be_to_cpu32 (exts[ex][0]) & ~(1 << 31)) << 23 \ + | grub_be_to_cpu32 (exts[ex][1]) >> 9) + +#define GRUB_XFS_EXTENT_BLOCK(exts,ex) \ + ((grub_uint64_t) (grub_be_to_cpu32 (exts[ex][1]) \ + & (0x1ff)) << 43 \ + | (grub_uint64_t) grub_be_to_cpu32 (exts[ex][2]) << 11 \ + | grub_be_to_cpu32 (exts[ex][3]) >> 21) + +#define GRUB_XFS_EXTENT_SIZE(exts,ex) \ + (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 20) - 1)) + +#define GRUB_XFS_ROUND_TO_DIRENT(pos) ((((pos) + 8 - 1) / 8) * 8) +#define GRUB_XFS_NEXT_DIRENT(pos,len) \ + (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2) + +static inline int +grub_xfs_inode_block (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + long long int inoinag = GRUB_XFS_INO_INOINAG (data, ino); + long long ag = GRUB_XFS_INO_AG (data, ino); + long long block; + + block = (inoinag >> 4) + ag * data->agsize; + block <<= (data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS); + return block; +} + + +static inline int +grub_xfs_inode_offset (struct grub_xfs_data *data, + grub_uint64_t ino) +{ + int inoag = GRUB_XFS_INO_INOINAG (data, ino); + return (inoag & ((1 << 4) - 1)) << 8; +} + + +static grub_err_t +grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, + struct grub_xfs_inode *inode) +{ + int block = grub_xfs_inode_block (data, ino); + int offset = grub_xfs_inode_offset (data, ino); + + /* Read the inode. */ + if (grub_disk_read (data->disk, block, offset, + sizeof (struct grub_xfs_inode), (char *) inode)) + return grub_errno; + + if (grub_strncmp ((char *) inode->magic, "IN", 2)) + return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode.\n"); + + return 0; +} + + +static grub_disk_addr_t +grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_xfs_btree_node *leaf = 0; + int ex, nrec; + grub_xfs_extent *exts; + grub_uint64_t ret = 0; + + if (node->inode.format == XFS_INODE_FORMAT_BTREE) + { + grub_uint64_t *keys; + + leaf = grub_malloc (node->data->sblock.bsize); + if (leaf == 0) + return 0; + + nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); + keys = &node->inode.data.btree.keys[0]; + do + { + int i; + + for (i = 0; i < nrec; i++) + { + if (fileblock < grub_be_to_cpu64 (keys[i])) + break; + } + + /* Sparse block. */ + if (i == 0) + { + grub_free (leaf); + return 0; + } + + if (grub_disk_read (node->data->disk, + grub_be_to_cpu64 (keys[i - 1 + XFS_INODE_EXTENTS]) + << (node->data->sblock.log2_bsize + - GRUB_DISK_SECTOR_BITS), + 0, node->data->sblock.bsize, (char *) leaf)) + return 0; + + if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) + { + grub_free (leaf); + grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node.\n"); + return 0; + } + + nrec = grub_be_to_cpu16 (leaf->numrecs); + keys = &leaf->keys[0]; + } while (leaf->level); + exts = (grub_xfs_extent *) keys; + } + else if (node->inode.format == XFS_INODE_FORMAT_EXT) + { + nrec = grub_be_to_cpu32 (node->inode.nextents); + exts = &node->inode.data.extents[0]; + } + else + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "xfs does not support inode format %d yet", + node->inode.format); + return 0; + } + + /* Iterate over each extent to figure out which extent has + the block we are looking for. */ + for (ex = 0; ex < nrec; ex++) + { + grub_uint64_t start = GRUB_XFS_EXTENT_BLOCK (exts, ex); + grub_uint64_t offset = GRUB_XFS_EXTENT_OFFSET (exts, ex); + grub_uint64_t size = GRUB_XFS_EXTENT_SIZE (exts, ex); + + /* Sparse block. */ + if (fileblock < offset) + break; + else if (fileblock < offset + size) + { + ret = (fileblock - offset + start); + break; + } + } + + if (leaf) + grub_free (leaf); + + return GRUB_XFS_FSB_TO_BLOCK(node->data, ret); +} + + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_xfs_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_xfs_read_block, + grub_be_to_cpu64 (node->inode.size), + node->data->sblock.log2_bsize + - GRUB_DISK_SECTOR_BITS); +} + + +static char * +grub_xfs_read_symlink (grub_fshelp_node_t node) +{ + int size = grub_be_to_cpu64 (node->inode.size); + + switch (node->inode.format) + { + case XFS_INODE_FORMAT_INO: + return grub_strndup (node->inode.data.raw, size); + + case XFS_INODE_FORMAT_EXT: + { + char *symlink; + grub_ssize_t numread; + + symlink = grub_malloc (size + 1); + if (!symlink) + return 0; + + numread = grub_xfs_read_file (node, 0, 0, size, symlink); + if (numread != size) + { + grub_free (symlink); + return 0; + } + symlink[size] = '\0'; + return symlink; + } + } + + return 0; +} + + +static enum grub_fshelp_filetype +grub_xfs_mode_to_filetype (grub_uint16_t mode) +{ + if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + return GRUB_FSHELP_DIR; + else if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + return GRUB_FSHELP_SYMLINK; + else if ((grub_be_to_cpu16 (mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + return GRUB_FSHELP_REG; + return GRUB_FSHELP_UNKNOWN; +} + + +static int +grub_xfs_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename); + + int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename) + { + struct grub_fshelp_node *fdiro; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + return 0; + + /* The inode should be read, otherwise the filetype can + not be determined. */ + fdiro->ino = ino; + fdiro->inode_read = 1; + fdiro->data = diro->data; + grub_xfs_read_inode (diro->data, ino, &fdiro->inode); + + return hook (filename, + grub_xfs_mode_to_filetype (fdiro->inode.mode), + fdiro); + } + + switch (diro->inode.format) + { + case XFS_INODE_FORMAT_INO: + { + struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0]; + int smallino = !diro->inode.data.dir.dirhead.smallino; + int i; + grub_uint64_t parent; + + /* If small inode numbers are used to pack the direntry, the + parent inode number is small too. */ + if (smallino) + { + parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4); + parent = grub_cpu_to_be64 (parent); + /* The header is a bit smaller than usual. */ + de = (struct grub_xfs_dir_entry *) ((char *) de - 4); + } + else + { + parent = diro->inode.data.dir.dirhead.parent.i8; + } + + /* Synthesize the direntries for `.' and `..'. */ + if (call_hook (diro->ino, ".")) + return 1; + + if (call_hook (parent, "..")) + return 1; + + for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) + { + grub_uint64_t ino; + void *inopos = (((char *) de) + + sizeof (struct grub_xfs_dir_entry) + + de->len - 1); + char name[de->len + 1]; + + if (smallino) + { + ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos); + ino = grub_cpu_to_be64 (ino); + } + else + ino = *(grub_uint64_t *) inopos; + + grub_memcpy (name, de->name, de->len); + name[de->len] = '\0'; + if (call_hook (ino, name)) + return 1; + + de = ((struct grub_xfs_dir_entry *) + (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len + + ((smallino ? sizeof (grub_uint32_t) + : sizeof (grub_uint64_t))) - 1)); + } + break; + } + + case XFS_INODE_FORMAT_BTREE: + case XFS_INODE_FORMAT_EXT: + { + grub_ssize_t numread; + char *dirblock; + grub_uint64_t blk; + int dirblk_size, dirblk_log2; + + dirblk_log2 = (dir->data->sblock.log2_bsize + + dir->data->sblock.log2_dirblk); + dirblk_size = 1 << dirblk_log2; + + dirblock = grub_malloc (dirblk_size); + if (! dirblock) + return 0; + + /* Iterate over every block the directory has. */ + for (blk = 0; + blk < (grub_be_to_cpu64 (dir->inode.size) + >> dirblk_log2); + blk++) + { + /* The header is skipped, the first direntry is stored + from byte 16. */ + int pos = 16; + int entries; + int tail_start = (dirblk_size + - sizeof (struct grub_xfs_dirblock_tail)); + + struct grub_xfs_dirblock_tail *tail; + tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; + + numread = grub_xfs_read_file (dir, 0, + blk << dirblk_log2, + dirblk_size, dirblock); + if (numread != dirblk_size) + return 0; + + entries = (grub_be_to_cpu32 (tail->leaf_count) + - grub_be_to_cpu32 (tail->leaf_stale)); + + /* Iterate over all entries within this block. */ + while (pos < (dirblk_size + - (int) sizeof (struct grub_xfs_dir2_entry))) + { + struct grub_xfs_dir2_entry *direntry; + grub_uint16_t *freetag; + char *filename; + + direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos]; + freetag = (grub_uint16_t *) direntry; + + if (*freetag == 0XFFFF) + { + grub_uint16_t *skip = (grub_uint16_t *) (freetag + 1); + + /* This entry is not used, go to the next one. */ + pos += grub_be_to_cpu16 (*skip); + + continue; + } + + filename = &dirblock[pos + sizeof (*direntry)]; + /* The byte after the filename is for the tag, which + is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + + if (call_hook (direntry->inode, filename)) + { + grub_free (dirblock); + return 1; + } + + /* Check if last direntry in this block is + reached. */ + entries--; + if (!entries) + break; + + /* Select the next directory entry. */ + pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len); + pos = GRUB_XFS_ROUND_TO_DIRENT (pos); + } + } + grub_free (dirblock); + break; + } + + default: + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "xfs does not support inode format %d yet", + diro->inode.format); + } + return 0; +} + + +static struct grub_xfs_data * +grub_xfs_mount (grub_disk_t disk) +{ + struct grub_xfs_data *data = 0; + + data = grub_malloc (sizeof (struct grub_xfs_data)); + if (!data) + return 0; + + /* Read the superblock. */ + if (grub_disk_read (disk, 0, 0, + sizeof (struct grub_xfs_sblock), (char *) &data->sblock)) + goto fail; + + if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)) + { + grub_error (GRUB_ERR_BAD_FS, "not a xfs filesystem"); + goto fail; + } + + data->diropen.data = data; + data->diropen.ino = data->sblock.rootino; + data->diropen.inode_read = 1; + data->bsize = grub_be_to_cpu32 (data->sblock.bsize); + data->agsize = grub_be_to_cpu32 (data->sblock.agsize); + + data->disk = disk; + data->inode = &data->diropen.inode; + data->pos = 0; + + grub_xfs_read_inode (data, data->diropen.ino, data->inode); + + return data; + fail: + + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an xfs filesystem"); + + grub_free (data); + + return 0; +} + + +static grub_err_t +grub_xfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + struct grub_xfs_data *data = 0;; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + grub_free (node); + + if (filetype == GRUB_FSHELP_DIR) + return hook (filename, 1); + else + return hook (filename, 0); + + return 0; + } + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_xfs_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_xfs_iterate_dir (fdiro, iterate); + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; + + return 0; +} + + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_xfs_open (struct grub_file *file, const char *name) +{ + struct grub_xfs_data *data; + struct grub_fshelp_node *fdiro = 0; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_xfs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir, + grub_xfs_read_symlink, GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, + &fdiro->inode, + sizeof (struct grub_xfs_inode)); + grub_free (fdiro); + + file->size = grub_be_to_cpu64 (data->inode->size); + file->data = data; + file->offset = 0; + + return 0; + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return grub_errno; +} + + +static grub_ssize_t +grub_xfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_xfs_data *data = + (struct grub_xfs_data *) file->data; + + return grub_xfs_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + + +static grub_err_t +grub_xfs_close (grub_file_t file) +{ + grub_free (file->data); + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + return GRUB_ERR_NONE; +} + + +static grub_err_t +grub_xfs_label (grub_device_t device, char **label) +{ + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_xfs_mount (disk); + if (data) + *label = grub_strndup ((char *) (data->sblock.label), 12); + else + *label = 0; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_xfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_xfs_data *data; + grub_disk_t disk = device->disk; + +#ifndef GRUB_UTIL + grub_dl_ref (my_mod); +#endif + + data = grub_xfs_mount (disk); + if (data) + { + *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); + grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); + } + else + *uuid = NULL; + +#ifndef GRUB_UTIL + grub_dl_unref (my_mod); +#endif + + grub_free (data); + + return grub_errno; +} + + + +static struct grub_fs grub_xfs_fs = + { + .name = "xfs", + .dir = grub_xfs_dir, + .open = grub_xfs_open, + .read = grub_xfs_read, + .close = grub_xfs_close, + .label = grub_xfs_label, + .uuid = grub_xfs_uuid, + .next = 0 + }; + +GRUB_MOD_INIT(xfs) +{ + grub_fs_register (&grub_xfs_fs); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(xfs) +{ + grub_fs_unregister (&grub_xfs_fs); +} diff --git a/gencmdlist.sh b/gencmdlist.sh new file mode 100644 index 0000000..5955066 --- /dev/null +++ b/gencmdlist.sh @@ -0,0 +1,18 @@ +#! /bin/sh +# +# Copyright (C) 2005 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Read source code from stdin and detect command names. + +module=$1 + +grep -v "^#" | sed -ne "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" diff --git a/gendistlist.sh b/gendistlist.sh new file mode 100755 index 0000000..011554d --- /dev/null +++ b/gendistlist.sh @@ -0,0 +1,43 @@ +#! /bin/sh +# +# Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. +# +# This gendistlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Generate a list of distributed files. + +EXTRA_DISTFILES="AUTHORS COPYING ChangeLog DISTLIST INSTALL NEWS README \ + THANKS TODO Makefile.in aclocal.m4 autogen.sh config.guess \ + config.h.in config.sub configure configure.ac gencmdlist.sh \ + gendistlist.sh genfslist.sh geninit.sh geninitheader.sh genkernsyms.sh.in \ + genmk.rb genmoddep.awk genmodsrc.sh genpartmaplist.sh gensymlist.sh.in + install-sh mkinstalldirs stamp-h.in" + +DISTDIRS="boot bus commands conf disk docs font fs hello hook include io kern lib \ + loader normal partmap term util video" + +LC_COLLATE=C +export LC_COLLATE + +for f in $EXTRA_DISTFILES; do + echo $f +done + +dir=`dirname $0` +cd $dir + +for dir in $DISTDIRS; do + for d in `find $dir -type d | sed '/\/\.svn$/d;\/\.svn\//d' | sort`; do + find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \ + -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \ + -o -name 'grub.cfg' -o -name 'README' -o -name '*.sc' -o -name 'mdate.sh' \ + | sort + done +done diff --git a/genfslist.sh b/genfslist.sh new file mode 100644 index 0000000..6fa7e92 --- /dev/null +++ b/genfslist.sh @@ -0,0 +1,26 @@ +#! /bin/sh +# +# Copyright (C) 2005,2008 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Read source code from stdin and detect fs names. + +module=$1 + +# Ignore kernel.mod. +if test $module = kernel; then + exit +fi + +# For now, this emits only a module name, if the module registers a filesystem. +if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then + echo $module +fi diff --git a/geninit.sh b/geninit.sh new file mode 100644 index 0000000..43d2d16 --- /dev/null +++ b/geninit.sh @@ -0,0 +1,75 @@ +#! /bin/sh +# +# Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +lst="$1" +shift + +header=`echo "${lst}" | sed -e "s/\.lst$/.h/g"` + +cat <. + */ + +#include <$header> + +EOF + +cat </dev/null; then + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_init ();/' + fi +done < ${lst} + +cat </dev/null; then + echo $line | sed -e 's/.*GRUB_MOD_INIT *(\([a-zA-Z0-9_]*\)).*/ grub_\1_fini ();/' + fi +done < ${lst} + +cat <. + */ + +EOF + +cat </dev/null 2>&1 && u="_" + +$CC -DGRUB_SYMBOL_GENERATOR=1 -E -I. -Iinclude -I"$srcdir/include" $* \ + | grep -v '^#' \ + | sed -n \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$u"'\1 kernel/;p;}' \ + | sort -u diff --git a/genmk.rb b/genmk.rb new file mode 100644 index 0000000..c41872c --- /dev/null +++ b/genmk.rb @@ -0,0 +1,359 @@ +#! /usr/bin/ruby -w +# +# Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# This genmk.rb is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +module Enumerable + def collect_with_index + ret = [] + self.each_with_index do |item, index| + ret.push(yield(item, index)) + end + ret + end +end + +class String + def to_var + self.gsub(/[^a-zA-Z0-9_@]/, '_') + end + + def suffix(str) + self.sub(/\.[^\.]*$/, '') + '.' + str + end + + def to_obj + self.sub(/\.[^\.]*$/, '').to_var + '.o' + end +end + +class Image + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + exe = @name.suffix('exec') + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' ') + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' ') + + "CLEANFILES += #{@name} #{exe} #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +#{@name}: #{exe} + $(OBJCOPY) -O binary -R .note -R .comment -R .note.gnu.build-id $< $@ + +#{exe}: #{objs_str} + $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end + extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end + dir = File.dirname(src) + + "#{obj}: #{src} $(#{src}_DEPENDENCIES) + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< +-include #{dep} + +" + end.join('') + end +end + +# Use PModule instead Module, to avoid name conflicting. +class PModule + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' ') + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' ') + pre_obj = 'pre-' + @name.suffix('o') + mod_src = 'mod-' + @name.suffix('c') + mod_obj = mod_src.suffix('o') + defsym = 'def-' + @name.suffix('lst') + undsym = 'und-' + @name.suffix('lst') + mod_name = File.basename(@name, '.mod') + symbolic_name = mod_name.sub(/\.[^\.]*$/, '') + + "CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym} +ifneq ($(#{prefix}_EXPORTS),no) +CLEANFILES += #{defsym} +DEFSYMFILES += #{defsym} +endif +MOSTLYCLEANFILES += #{deps_str} +UNDSYMFILES += #{undsym} + +#{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) $(MODULE_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj} + if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + +#{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str} + -rm -f $@ + $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str} + +#{mod_obj}: #{mod_src} + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $< + +#{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh + sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(#{prefix}_EXPORTS),no) +#{defsym}: #{pre_obj} + $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ +endif + +#{undsym}: #{pre_obj} + echo '#{mod_name}' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + command = 'cmd-' + obj.suffix('lst') + fs = 'fs-' + obj.suffix('lst') + partmap = 'partmap-' + obj.suffix('lst') + dep = deps[i] + flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end + extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end + dir = File.dirname(src) + + "#{obj}: #{src} $(#{src}_DEPENDENCIES) + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< +-include #{dep} + +CLEANFILES += #{command} #{fs} #{partmap} +COMMANDFILES += #{command} +FSFILES += #{fs} +PARTMAPFILES += #{partmap} + +#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh + set -e; \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + | sh $(srcdir)/gencmdlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) + +#{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh + set -e; \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) + +#{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh + set -e; \ + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \ + | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) + + +" + end.join('') + end +end + +class Utility + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' '); + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' '); + + "CLEANFILES += #{@name}$(EXEEXT) #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} + $(CC) -o $@ #{objs_str} $(LDFLAGS) $(#{prefix}_LDFLAGS) + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + dir = File.dirname(src) + + "#{obj}: #{src} $(#{src}_DEPENDENCIES) + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -MD -c -o $@ $< +-include #{dep} + +" + end.join('') + end +end + +class Program + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + prefix = @name.to_var + objs = sources.collect do |src| + raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src + prefix + '-' + src.to_obj + end + objs_str = objs.join(' '); + deps = objs.collect {|obj| obj.suffix('d')} + deps_str = deps.join(' '); + + "CLEANFILES += #{@name} #{objs_str} +MOSTLYCLEANFILES += #{deps_str} + +#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} + $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + +" + objs.collect_with_index do |obj, i| + src = sources[i] + fake_obj = File.basename(src).suffix('o') + dep = deps[i] + dir = File.dirname(src) + + "#{obj}: #{src} $(#{src}_DEPENDENCIES) + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -MD -c -o $@ $< +-include #{dep} + +" + end.join('') + end +end + +class Script + def initialize(dir, name) + @dir = dir + @name = name + end + attr_reader :dir, :name + + def rule(sources) + if sources.length != 1 + raise "only a single source file must be specified for a script" + end + src = sources[0] + if /\.in$/ !~ src + raise "unknown source file `#{src}'" + end + + "CLEANFILES += #{@name} + +#{@name}: #{src} $(#{src}_DEPENDENCIES) config.status + ./config.status --file=#{name}:#{src} + chmod +x $@ + +" + end +end + +images = [] +utils = [] +pmodules = [] +programs = [] +scripts = [] + +l = gets +print l +print "# Generated by genmk.rb, please don't edit!\n" + +cont = false +s = nil +while l = gets + if cont + s += l + else + s = l + end + + print l + cont = (/\\$/ =~ l) + unless cont + s.gsub!(/\\\n/, ' ') + + if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ s + var, args = $1, $2 + + if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/ + prefix, type = $1, $2 + + case type + when 'IMAGES' + images += args.split(/\s+/).collect do |img| + Image.new(prefix, img) + end + + when 'MODULES' + pmodules += args.split(/\s+/).collect do |pmod| + PModule.new(prefix, pmod) + end + + when 'UTILITIES' + utils += args.split(/\s+/).collect do |util| + Utility.new(prefix, util) + end + + when 'PROGRAMS' + programs += args.split(/\s+/).collect do |prog| + Program.new(prefix, prog) + end + + when 'SCRIPTS' + scripts += args.split(/\s+/).collect do |script| + Script.new(prefix, script) + end + + when 'SOURCES' + if img = images.detect() {|i| i.name.to_var == prefix} + print img.rule(args.split(/\s+/)) + elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix} + print pmod.rule(args.split(/\s+/)) + elsif util = utils.detect() {|u| u.name.to_var == prefix} + print util.rule(args.split(/\s+/)) + elsif program = programs.detect() {|u| u.name.to_var == prefix} + print program.rule(args.split(/\s+/)) + elsif script = scripts.detect() {|s| s.name.to_var == prefix} + print script.rule(args.split(/\s+/)) + end + end + end + + end + + end + +end + diff --git a/genmoddep.awk b/genmoddep.awk new file mode 100644 index 0000000..c079b36 --- /dev/null +++ b/genmoddep.awk @@ -0,0 +1,62 @@ +#! /usr/bin/awk -f +# +# Copyright (C) 2006 Free Software Foundation, Inc. +# +# This genmoddep.awk is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Read defined symbols from stdin. +BEGIN { + while (getline <"/dev/stdin") { + symtab[$1] = $2 + } +} + +# The first line contains a module name. +FNR == 1 { + module = $1 + next +}; + +# The rest is undefined symbols. +{ + if ($1 in symtab) { + modtab[module] = modtab[module] " " symtab[$1]; + } + else { + printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; + error++; + exit; + } +} + +# Output the result. +END { + if (error == 1) + exit 1; + + for (mod in modtab) { + # Remove duplications. + split(modtab[mod], depmods, " "); + for (depmod in uniqmods) { + delete uniqmods[depmod]; + } + for (i in depmods) { + depmod = depmods[i]; + # Ignore kernel, as always loaded. + if (depmod != "kernel") + uniqmods[depmod] = 1; + } + modlist = "" + for (depmod in uniqmods) { + modlist = modlist " " depmod; + } + printf "%s:%s\n", mod, modlist; + } +} diff --git a/genmodsrc.sh b/genmodsrc.sh new file mode 100644 index 0000000..2d42055 --- /dev/null +++ b/genmodsrc.sh @@ -0,0 +1,47 @@ +#! /bin/sh +# +# Copyright (C) 2002,2007 Free Software Foundation, Inc. +# +# This genmodsrc.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +set -e + +mod_name="$1" +deps="$2" + +cat <. + */ + +#include + +EOF + +echo "GRUB_MOD_NAME(${mod_name});" + +for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do + echo "GRUB_MOD_DEP(${mod});" +done diff --git a/genpartmaplist.sh b/genpartmaplist.sh new file mode 100644 index 0000000..fceb0f8 --- /dev/null +++ b/genpartmaplist.sh @@ -0,0 +1,26 @@ +#! /bin/sh +# +# Copyright (C) 2005, 2008 Free Software Foundation, Inc. +# +# This script is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Read source code from stdin and detect partmap names. + +module=$1 + +# Ignore kernel.mod. +if test $module = kernel; then + exit +fi + +# For now, this emits only a module name, if the module registers a partition map. +if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then + echo $module +fi diff --git a/gensymlist.sh.in b/gensymlist.sh.in new file mode 100644 index 0000000..8f50b99 --- /dev/null +++ b/gensymlist.sh.in @@ -0,0 +1,77 @@ +#! /bin/sh +# +# Copyright (C) 2002,2006,2007,2008 Free Software Foundation, Inc. +# +# This gensymlist.sh.in is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +### The configure script will replace these variables. + +: ${srcdir=@srcdir@} +: ${CC=@CC@} + + +cat <. + */ + +EOF + +for i in $*; do + echo "#include <$i>" +done + +cat < sizeof (tab[0])); + for (p = tab; p->name; p++) + grub_dl_register_symbol (p->name, p->addr, 0); +} +EOF diff --git a/hello/hello.c b/hello/hello.c new file mode 100644 index 0000000..70cbf60 --- /dev/null +++ b/hello/hello.c @@ -0,0 +1,47 @@ +/* hello.c - test module for dynamic loading */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007 Free Software Foundation, Inc. + * Copyright (C) 2003 NIIBE Yutaka + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_hello (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_printf ("Hello World\n"); + return 0; +} + +GRUB_MOD_INIT(hello) +{ + (void)mod; /* To stop warning. */ + grub_register_command ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH, + "hello", "Say hello", 0); +} + +GRUB_MOD_FINI(hello) +{ + grub_unregister_command ("hello"); +} diff --git a/hook/datehook.c b/hook/datehook.c new file mode 100644 index 0000000..9419d48 --- /dev/null +++ b/hook/datehook.c @@ -0,0 +1,106 @@ +/* datehook.c - Module to install datetime hooks. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static char *grub_datetime_names[] = +{ + "YEAR", + "MONTH", + "DAY", + "HOUR", + "MINUTE", + "SECOND", + "WEEKDAY", +}; + +static char * +grub_read_hook_datetime (struct grub_env_var *var, + const char *val __attribute__ ((unused))) +{ + struct grub_datetime datetime; + static char buf[6]; + + buf[0] = 0; + if (! grub_get_datetime (&datetime)) + { + int i; + + for (i = 0; i < 7; i++) + if (! grub_strcmp (var->name, grub_datetime_names[i])) + { + int n; + + switch (i) + { + case 0: + n = datetime.year; + break; + case 1: + n = datetime.month; + break; + case 2: + n = datetime.day; + break; + case 3: + n = datetime.hour; + break; + case 4: + n = datetime.minute; + break; + case 5: + n = datetime.second; + break; + default: + return grub_get_weekday_name (&datetime); + } + + grub_sprintf (buf, "%d", n); + break; + } + } + + return buf; +} + +GRUB_MOD_INIT(datetime) +{ + (void)mod; /* To stop warning. */ + int i; + + for (i = 0; i < 7; i++) + grub_register_variable_hook (grub_datetime_names[i], + grub_read_hook_datetime, 0); +} + +GRUB_MOD_FINI(datetime) +{ + int i; + + for (i = 0; i < 7; i++) + { + grub_register_variable_hook (grub_datetime_names[i], 0, 0); + grub_env_unset (grub_datetime_names[i]); + } +} diff --git a/include/grub/acorn_filecore.h b/include/grub/acorn_filecore.h new file mode 100644 index 0000000..6cda6cf --- /dev/null +++ b/include/grub/acorn_filecore.h @@ -0,0 +1,53 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ACORN_FILECORE_HEADER +#define GRUB_ACORN_FILECORE_HEADER 1 + +#include + +struct grub_filecore_disc_record +{ + grub_uint8_t log2secsize; + grub_uint8_t secspertrack; + grub_uint8_t heads; + grub_uint8_t density; + grub_uint8_t idlen; + grub_uint8_t log2bpmb; + grub_uint8_t skew; + grub_uint8_t bootoption; + /* In bits 0-5, flags in bits 6 and 7. */ + grub_uint8_t lowsector; + grub_uint8_t nzones; + grub_uint16_t zone_spare; + grub_uint32_t root_address; + /* Disc size in bytes. */ + grub_uint32_t disc_size; + grub_uint16_t cycle_id; + char disc_name[10]; + /* Yes, it is 32 bits! */ + grub_uint32_t disctype; + /* Most significant part of the disc size. */ + grub_uint32_t disc_size2; + grub_uint8_t share_size; + grub_uint8_t big_flag; + grub_uint8_t reserved[18]; +}; + + +#endif /* ! GRUB_ACORN_FILECORE_HEADER */ diff --git a/include/grub/aout.h b/include/grub/aout.h new file mode 100644 index 0000000..c5650dd --- /dev/null +++ b/include/grub/aout.h @@ -0,0 +1,91 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_AOUT_HEADER +#define GRUB_AOUT_HEADER 1 + +#include + +struct grub_aout32_header +{ + grub_uint32_t a_midmag; /* htonl(flags<<26 | mid<<16 | magic) */ + grub_uint32_t a_text; /* text segment size */ + grub_uint32_t a_data; /* initialized data size */ + grub_uint32_t a_bss; /* uninitialized data size */ + grub_uint32_t a_syms; /* symbol table size */ + grub_uint32_t a_entry; /* entry point */ + grub_uint32_t a_trsize; /* text relocation size */ + grub_uint32_t a_drsize; /* data relocation size */ +}; + +struct grub_aout64_header +{ + grub_uint32_t a_midmag; /* htonl(flags<<26 | mid<<16 | magic) */ + grub_uint64_t a_text; /* text segment size */ + grub_uint64_t a_data; /* initialized data size */ + grub_uint64_t a_bss; /* uninitialized data size */ + grub_uint64_t a_syms; /* symbol table size */ + grub_uint64_t a_entry; /* entry point */ + grub_uint64_t a_trsize; /* text relocation size */ + grub_uint64_t a_drsize; /* data relocation size */ +}; + +union grub_aout_header +{ + struct grub_aout32_header aout32; + struct grub_aout64_header aout64; +}; + +#define AOUT_TYPE_NONE 0 +#define AOUT_TYPE_AOUT32 1 +#define AOUT_TYPE_AOUT64 6 + +#define AOUT32_OMAGIC 0x107 /* 0407 old impure format */ +#define AOUT32_NMAGIC 0x108 /* 0410 read-only text */ +#define AOUT32_ZMAGIC 0x10b /* 0413 demand load format */ +#define AOUT32_QMAGIC 0xcc /* 0314 "compact" demand load format */ + +#define AOUT64_OMAGIC 0x1001 +#define AOUT64_ZMAGIC 0x1002 +#define AOUT64_NMAGIC 0x1003 + +#define AOUT_MID_ZERO 0 /* unknown - implementation dependent */ +#define AOUT_MID_SUN010 1 /* sun 68010/68020 binary */ +#define AOUT_MID_SUN020 2 /* sun 68020-only binary */ +#define AOUT_MID_I386 134 /* i386 BSD binary */ +#define AOUT_MID_SPARC 138 /* sparc */ +#define AOUT_MID_HP200 200 /* hp200 (68010) BSD binary */ +#define AOUT_MID_HP300 300 /* hp300 (68020+68881) BSD binary */ +#define AOUT_MID_HPUX 0x20C /* hp200/300 HP-UX binary */ +#define AOUT_MID_HPUX800 0x20B /* hp800 HP-UX binary */ + +#define AOUT_FLAG_PIC 0x10 /* contains position independent code */ +#define AOUT_FLAG_DYNAMIC 0x20 /* contains run-time link-edit info */ +#define AOUT_FLAG_DPMASK 0x30 /* mask for the above */ + +#define AOUT_GETMAGIC(header) ((header).a_midmag & 0xffff) +#define AOUT_GETMID(header) ((header).a_midmag >> 16) & 0x03ff) +#define AOUT_GETFLAG(header) ((header).a_midmag >> 26) & 0x3f) + +int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header); + +grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset, + grub_addr_t load_addr, int load_size, + grub_addr_t bss_end_addr); + +#endif /* ! GRUB_AOUT_HEADER */ diff --git a/include/grub/arg.h b/include/grub/arg.h new file mode 100644 index 0000000..bb9ce7b --- /dev/null +++ b/include/grub/arg.h @@ -0,0 +1,65 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ARG_HEADER +#define GRUB_ARG_HEADER 1 + +#include +#include +#include + +enum grub_arg_type + { + ARG_TYPE_NONE, + ARG_TYPE_STRING, + ARG_TYPE_INT, + ARG_TYPE_DEVICE, + ARG_TYPE_FILE, + ARG_TYPE_DIR, + ARG_TYPE_PATHNAME + }; + +typedef enum grub_arg_type grub_arg_type_t; + +/* Flags for the option field op grub_arg_option. */ +#define GRUB_ARG_OPTION_OPTIONAL (1 << 1) + +enum grub_key_type + { + GRUB_KEY_ARG = -1, + GRUB_KEY_END = -2 + }; +typedef enum grub_key_type grub_arg_key_type_t; + +struct grub_arg_option +{ + const char *longarg; + int shortarg; + int flags; + char *doc; + char *arg; + grub_arg_type_t type; +}; + +struct grub_arg_list +{ + int set; + char *arg; +}; + +#endif /* ! GRUB_ARG_HEADER */ diff --git a/include/grub/ata.h b/include/grub/ata.h new file mode 100644 index 0000000..aaa2e14 --- /dev/null +++ b/include/grub/ata.h @@ -0,0 +1,168 @@ +/* ata.h - ATA disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ATA_HEADER +#define GRUB_ATA_HEADER 1 + +#include +#include +/* XXX: For now this only works on i386. */ +#include + +typedef enum + { + GRUB_ATA_CHS, + GRUB_ATA_LBA, + GRUB_ATA_LBA48 + } grub_ata_addressing_t; + +#define GRUB_ATA_REG_DATA 0 +#define GRUB_ATA_REG_ERROR 1 +#define GRUB_ATA_REG_FEATURES 1 +#define GRUB_ATA_REG_SECTORS 2 +#define GRUB_ATAPI_REG_IREASON 2 +#define GRUB_ATA_REG_SECTNUM 3 +#define GRUB_ATA_REG_CYLLSB 4 +#define GRUB_ATA_REG_CYLMSB 5 +#define GRUB_ATA_REG_LBALOW 3 +#define GRUB_ATA_REG_LBAMID 4 +#define GRUB_ATAPI_REG_CNTLOW 4 +#define GRUB_ATA_REG_LBAHIGH 5 +#define GRUB_ATAPI_REG_CNTHIGH 5 +#define GRUB_ATA_REG_DISK 6 +#define GRUB_ATA_REG_CMD 7 +#define GRUB_ATA_REG_STATUS 7 + +#define GRUB_ATA_REG2_CONTROL 0 + +#define GRUB_ATA_STATUS_ERR 0x01 +#define GRUB_ATA_STATUS_INDEX 0x02 +#define GRUB_ATA_STATUS_ECC 0x04 +#define GRUB_ATA_STATUS_DRQ 0x08 +#define GRUB_ATA_STATUS_SEEK 0x10 +#define GRUB_ATA_STATUS_WRERR 0x20 +#define GRUB_ATA_STATUS_READY 0x40 +#define GRUB_ATA_STATUS_BUSY 0x80 + +/* ATAPI interrupt reason values (I/O, D/C bits). */ +#define GRUB_ATAPI_IREASON_MASK 0x3 +#define GRUB_ATAPI_IREASON_DATA_OUT 0x0 +#define GRUB_ATAPI_IREASON_CMD_OUT 0x1 +#define GRUB_ATAPI_IREASON_DATA_IN 0x2 +#define GRUB_ATAPI_IREASON_ERROR 0x3 + +enum grub_ata_commands + { + GRUB_ATA_CMD_CHECK_POWER_MODE = 0xe5, + GRUB_ATA_CMD_IDENTIFY_DEVICE = 0xec, + GRUB_ATA_CMD_IDENTIFY_PACKET_DEVICE = 0xa1, + GRUB_ATA_CMD_IDLE = 0xe3, + GRUB_ATA_CMD_PACKET = 0xa0, + GRUB_ATA_CMD_READ_SECTORS = 0x20, + GRUB_ATA_CMD_READ_SECTORS_EXT = 0x24, + GRUB_ATA_CMD_SECURITY_FREEZE_LOCK = 0xf5, + GRUB_ATA_CMD_SET_FEATURES = 0xef, + GRUB_ATA_CMD_SLEEP = 0xe6, + GRUB_ATA_CMD_SMART = 0xb0, + GRUB_ATA_CMD_STANDBY_IMMEDIATE = 0xe0, + GRUB_ATA_CMD_WRITE_SECTORS = 0x30, + GRUB_ATA_CMD_WRITE_SECTORS_EXT = 0x34, + }; + +enum grub_ata_timeout_milliseconds + { + GRUB_ATA_TOUT_STD = 1000, /* 1s standard timeout. */ + GRUB_ATA_TOUT_DATA = 10000 /* 10s DATA I/O timeout. */ + }; + +struct grub_ata_device +{ + /* IDE port to use. */ + int port; + + /* IO addresses on which the registers for this device can be + found. */ + int ioaddress; + int ioaddress2; + + /* Two devices can be connected to a single cable. Use this field + to select device 0 (commonly known as "master") or device 1 + (commonly known as "slave"). */ + int device; + + /* Addressing methods available for accessing this device. If CHS + is only available, use that. Otherwise use LBA, except for the + high sectors. In that case use LBA48. */ + grub_ata_addressing_t addr; + + /* Sector count. */ + grub_uint64_t size; + + /* CHS maximums. */ + grub_uint16_t cylinders; + grub_uint16_t heads; + grub_uint16_t sectors_per_track; + + /* Set to 0 for ATA, set to 1 for ATAPI. */ + int atapi; + + struct grub_ata_device *next; +}; + +grub_err_t EXPORT_FUNC(grub_ata_wait_not_busy) (struct grub_ata_device *dev, + int milliseconds); +grub_err_t EXPORT_FUNC(grub_ata_wait_drq) (struct grub_ata_device *dev, + int rw, int milliseconds); +void EXPORT_FUNC(grub_ata_pio_read) (struct grub_ata_device *dev, + char *buf, grub_size_t size); + +static inline void +grub_ata_regset (struct grub_ata_device *dev, int reg, int val) +{ + grub_outb (val, dev->ioaddress + reg); +} + +static inline grub_uint8_t +grub_ata_regget (struct grub_ata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress + reg); +} + +static inline void +grub_ata_regset2 (struct grub_ata_device *dev, int reg, int val) +{ + grub_outb (val, dev->ioaddress2 + reg); +} + +static inline grub_uint8_t +grub_ata_regget2 (struct grub_ata_device *dev, int reg) +{ + return grub_inb (dev->ioaddress2 + reg); +} + +static inline grub_err_t +grub_ata_check_ready (struct grub_ata_device *dev) +{ + if (grub_ata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY) + return grub_ata_wait_not_busy (dev, GRUB_ATA_TOUT_STD); + + return GRUB_ERR_NONE; +} + +#endif /* ! GRUB_ATA_HEADER */ diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h new file mode 100644 index 0000000..42c439d --- /dev/null +++ b/include/grub/bitmap.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BITMAP_HEADER +#define GRUB_BITMAP_HEADER 1 + +#include +#include +#include +#include + +struct grub_video_bitmap +{ + /* Bitmap format description. */ + struct grub_video_mode_info mode_info; + + /* Pointer to bitmap data formatted according to mode_info. */ + void *data; +}; + +struct grub_video_bitmap_reader +{ + /* File extension for this bitmap type (including dot). */ + const char *extension; + + /* Reader function to load bitmap. */ + grub_err_t (*reader) (struct grub_video_bitmap **bitmap, + const char *filename); + + /* Next reader. */ + struct grub_video_bitmap_reader *next; +}; +typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t; + +void grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader); +void grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader); + +grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, + unsigned int width, unsigned int height, + enum grub_video_blit_format blit_format); + +grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap); + +grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, + const char *filename); + +unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap); +unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap); + +void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, + struct grub_video_mode_info *mode_info); + +void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap); + +#endif /* ! GRUB_BITMAP_HEADER */ diff --git a/include/grub/boot.h b/include/grub/boot.h new file mode 100644 index 0000000..2357748 --- /dev/null +++ b/include/grub/boot.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BOOT_HEADER +#define GRUB_BOOT_HEADER 1 + +#define GRUB_BOOT_VERSION_MAJOR 4 +#define GRUB_BOOT_VERSION_MINOR 0 +#define GRUB_BOOT_VERSION ((GRUB_BOOT_VERSION_MINOR << 8) \ + | GRUB_BOOT_VERSION_MAJOR) + +#endif /* ! GRUB_BOOT_HEADER */ diff --git a/include/grub/bufio.h b/include/grub/bufio.h new file mode 100644 index 0000000..9a2294c --- /dev/null +++ b/include/grub/bufio.h @@ -0,0 +1,28 @@ +/* bufio.h - prototypes for bufio */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BUFIO_H +#define GRUB_BUFIO_H 1 + +#include + +grub_file_t grub_bufio_open (grub_file_t io, int size); +grub_file_t grub_buffile_open (const char *name, int size); + +#endif /* ! GRUB_BUFIO_H */ diff --git a/include/grub/cache.h b/include/grub/cache.h new file mode 100644 index 0000000..745af43 --- /dev/null +++ b/include/grub/cache.h @@ -0,0 +1,28 @@ +/* cache.h - Flush the processor's cache. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CACHE_H +#define GRUB_CACHE_H 1 + +#include +#include + +void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); + +#endif /* ! GRUB_CACHE_HEADER */ diff --git a/include/grub/device.h b/include/grub/device.h new file mode 100644 index 0000000..f0e8a8c --- /dev/null +++ b/include/grub/device.h @@ -0,0 +1,41 @@ +/* device.h - device manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_DEVICE_HEADER +#define GRUB_DEVICE_HEADER 1 + +#include +#include + +struct grub_disk; +struct grub_net; +struct grub_fs; + +struct grub_device +{ + struct grub_disk *disk; + struct grub_net *net; +}; +typedef struct grub_device *grub_device_t; + +grub_device_t EXPORT_FUNC(grub_device_open) (const char *name); +grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device); +int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name)); + +#endif /* ! GRUB_DEVICE_HEADER */ diff --git a/include/grub/disk.h b/include/grub/disk.h new file mode 100644 index 0000000..1e8046a --- /dev/null +++ b/include/grub/disk.h @@ -0,0 +1,182 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_DISK_HEADER +#define GRUB_DISK_HEADER 1 + +#include +#include +#include +#include + +/* These are used to set a device id. When you add a new disk device, + you must define a new id for it here. */ +enum grub_disk_dev_id + { + GRUB_DISK_DEVICE_BIOSDISK_ID, + GRUB_DISK_DEVICE_OFDISK_ID, + GRUB_DISK_DEVICE_LOOPBACK_ID, + GRUB_DISK_DEVICE_EFIDISK_ID, + GRUB_DISK_DEVICE_RAID_ID, + GRUB_DISK_DEVICE_LVM_ID, + GRUB_DISK_DEVICE_HOST_ID, + GRUB_DISK_DEVICE_ATA_ID, + GRUB_DISK_DEVICE_MEMDISK_ID, + GRUB_DISK_DEVICE_NAND_ID, + GRUB_DISK_DEVICE_UUID_ID, + GRUB_DISK_DEVICE_PXE_ID, + GRUB_DISK_DEVICE_SCSI_ID, + }; + +struct grub_disk; +#ifdef GRUB_UTIL +struct grub_disk_memberlist; +#endif + +/* Disk device. */ +struct grub_disk_dev +{ + /* The device name. */ + const char *name; + + /* The device id used by the cache manager. */ + unsigned long id; + + /* Call HOOK with each device name, until HOOK returns non-zero. */ + int (*iterate) (int (*hook) (const char *name)); + + /* Open the device named NAME, and set up DISK. */ + grub_err_t (*open) (const char *name, struct grub_disk *disk); + + /* Close the disk DISK. */ + void (*close) (struct grub_disk *disk); + + /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */ + grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, char *buf); + + /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK. */ + grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf); + +#ifdef GRUB_UTIL + struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk); +#endif + + /* The next disk device. */ + struct grub_disk_dev *next; +}; +typedef struct grub_disk_dev *grub_disk_dev_t; + +struct grub_partition; + +/* Disk. */ +struct grub_disk +{ + /* The disk name. */ + const char *name; + + /* The underlying disk device. */ + grub_disk_dev_t dev; + + /* The total number of sectors. */ + grub_uint64_t total_sectors; + + /* If partitions can be stored. */ + int has_partitions; + + /* The id used by the disk cache manager. */ + unsigned long id; + + /* The partition information. This is machine-specific. */ + struct grub_partition *partition; + + /* Called when a sector was read. OFFSET is between 0 and + the sector size minus 1, and LENGTH is between 0 and the sector size. */ + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length); + + /* Device-specific data. */ + void *data; +}; +typedef struct grub_disk *grub_disk_t; + +#ifdef GRUB_UTIL +struct grub_disk_memberlist +{ + grub_disk_t disk; + struct grub_disk_memberlist *next; +}; +typedef struct grub_disk_memberlist *grub_disk_memberlist_t; +#endif + +/* The sector size. */ +#define GRUB_DISK_SECTOR_SIZE 0x200 +#define GRUB_DISK_SECTOR_BITS 9 + +/* The maximum number of disk caches. */ +#define GRUB_DISK_CACHE_NUM 1021 + +/* The size of a disk cache in sector units. */ +#define GRUB_DISK_CACHE_SIZE 8 +#define GRUB_DISK_CACHE_BITS 3 + +/* This is called from the memory manager. */ +void grub_disk_cache_invalidate_all (void); + +void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev); +void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev); +int EXPORT_FUNC(grub_disk_dev_iterate) (int (*hook) (const char *name)); + +grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name); +void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk); +grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + char *buf); +grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, + grub_size_t size, + const char *buf); + +grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk); + +extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void); +extern int EXPORT_VAR(grub_disk_firmware_is_tainted); + +/* ATA pass through parameters and function. */ +struct grub_disk_ata_pass_through_parms +{ + grub_uint8_t taskfile[8]; + void * buffer; + int size; +}; + +extern grub_err_t (* EXPORT_VAR(grub_disk_ata_pass_through)) (grub_disk_t, + struct grub_disk_ata_pass_through_parms *); + +#ifdef GRUB_UTIL +void grub_raid_init (void); +void grub_raid_fini (void); +void grub_lvm_init (void); +void grub_lvm_fini (void); +#endif + +#endif /* ! GRUB_DISK_HEADER */ diff --git a/include/grub/dl.h b/include/grub/dl.h new file mode 100644 index 0000000..5e46374 --- /dev/null +++ b/include/grub/dl.h @@ -0,0 +1,96 @@ +/* dl.h - types and prototypes for loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_DL_H +#define GRUB_DL_H 1 + +#include +#include +#include + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +void grub_##name##_init (void); \ +void \ +grub_##name##_init (void) { grub_mod_init (0); } \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +void grub_##name##_fini (void); \ +void \ +grub_##name##_fini (void) { grub_mod_fini (); } \ +static void \ +grub_mod_fini (void) + +#define GRUB_MOD_NAME(name) \ +__asm__ (".section .modname\n.string \"" #name "\"\n") + +#define GRUB_MOD_DEP(name) \ +__asm__ (".section .moddeps\n.string \"" #name "\"\n") + +struct grub_dl_segment +{ + struct grub_dl_segment *next; + void *addr; + grub_size_t size; + unsigned section; +}; +typedef struct grub_dl_segment *grub_dl_segment_t; + +struct grub_dl; + +struct grub_dl_dep +{ + struct grub_dl_dep *next; + struct grub_dl *mod; +}; +typedef struct grub_dl_dep *grub_dl_dep_t; + +struct grub_dl +{ + char *name; + int ref_count; + grub_dl_dep_t dep; + grub_dl_segment_t segment; + void (*init) (struct grub_dl *mod); + void (*fini) (void); +}; +typedef struct grub_dl *grub_dl_t; + +grub_err_t EXPORT_FUNC(grub_dl_check_header) (void *ehdr, grub_size_t size); +grub_dl_t EXPORT_FUNC(grub_dl_load_file) (const char *filename); +grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); +grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); +int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); +void grub_dl_unload_unneeded (void); +void grub_dl_unload_all (void); +int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); +void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); +grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); +grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr, + grub_dl_t mod); +void *EXPORT_FUNC(grub_dl_resolve_symbol) (const char *name); + +grub_err_t grub_arch_dl_check_header (void *ehdr); +grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); + +#endif /* ! GRUB_DL_H */ diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h new file mode 100644 index 0000000..44b7d27 --- /dev/null +++ b/include/grub/efi/api.h @@ -0,0 +1,1136 @@ +/* efi.h - declare EFI types and functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_API_HEADER +#define GRUB_EFI_API_HEADER 1 + +#include + +/* For consistency and safety, we name the EFI-defined types differently. + All names are transformed into lower case, _t appended, and + grub_efi_ prepended. */ + +/* Constants. */ +#define GRUB_EFI_EVT_TIMER 0x80000000 +#define GRUB_EFI_EVT_RUNTIME 0x40000000 +#define GRUB_EFI_EVT_RUNTIME_CONTEXT 0x20000000 +#define GRUB_EFI_EVT_NOTIFY_WAIT 0x00000100 +#define GRUB_EFI_EVT_NOTIFY_SIGNAL 0x00000200 +#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define GRUB_EFI_TPL_APPLICATION 4 +#define GRUB_EFI_TPL_CALLBACK 8 +#define GRUB_EFI_TPL_NOTIFY 16 +#define GRUB_EFI_TPL_HIGH_LEVEL 31 + +#define GRUB_EFI_MEMORY_UC 0x0000000000000001 +#define GRUB_EFI_MEMORY_WC 0x0000000000000002 +#define GRUB_EFI_MEMORY_WT 0x0000000000000004 +#define GRUB_EFI_MEMORY_WB 0x0000000000000008 +#define GRUB_EFI_MEMORY_UCE 0x0000000000000010 +#define GRUB_EFI_MEMORY_WP 0x0000000000001000 +#define GRUB_EFI_MEMORY_RP 0x0000000000002000 +#define GRUB_EFI_MEMORY_XP 0x0000000000004000 +#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 + +#define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 + +#define GRUB_EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define GRUB_EFI_TIME_IN_DAYLIGHT 0x02 + +#define GRUB_EFI_UNSPECIFIED_TIMEZONE 0x07FF + +#define GRUB_EFI_OPTIONAL_PTR 0x00000001 + +#define GRUB_EFI_LOADED_IMAGE_GUID \ + { 0x5b1b31a1, 0x9562, 0x11d2, \ + { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_DISK_IO_GUID \ + { 0xce345171, 0xba0b, 0x11d2, \ + { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_BLOCK_IO_GUID \ + { 0x964e5b21, 0x6459, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_DEVICE_PATH_GUID \ + { 0x09576e91, 0x6d3f, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +/* Enumerations. */ +enum grub_efi_timer_delay + { + GRUB_EFI_TIMER_CANCEL, + GRUB_EFI_TIMER_PERIODIC, + GRUB_EFI_TIMER_RELATIVE + }; +typedef enum grub_efi_timer_delay grub_efi_timer_delay_t; + +enum grub_efi_allocate_type + { + GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_MAX_ALLOCATION_TYPE + }; +typedef enum grub_efi_allocate_type grub_efi_allocate_type_t; + +enum grub_efi_memory_type + { + GRUB_EFI_RESERVED_MEMORY_TYPE, + GRUB_EFI_LOADER_CODE, + GRUB_EFI_LOADER_DATA, + GRUB_EFI_BOOT_SERVICES_CODE, + GRUB_EFI_BOOT_SERVICES_DATA, + GRUB_EFI_RUNTIME_SERVICES_CODE, + GRUB_EFI_RUNTIME_SERVICES_DATA, + GRUB_EFI_CONVENTIONAL_MEMORY, + GRUB_EFI_UNUSABLE_MEMORY, + GRUB_EFI_ACPI_RECLAIM_MEMORY, + GRUB_EFI_ACPI_MEMORY_NVS, + GRUB_EFI_MEMORY_MAPPED_IO, + GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, + GRUB_EFI_PAL_CODE, + GRUB_EFI_MAX_MEMORY_TYPE + }; +typedef enum grub_efi_memory_type grub_efi_memory_type_t; + +enum grub_efi_interface_type + { + GRUB_EFI_NATIVE_INTERFACE + }; +typedef enum grub_efi_interface_type grub_efi_interface_type_t; + +enum grub_efi_locate_search_type + { + GRUB_EFI_ALL_HANDLES, + GRUB_EFI_BY_REGISTER_NOTIFY, + GRUB_EFI_BY_PROTOCOL + }; +typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t; + +enum grub_efi_reset_type + { + GRUB_EFI_RESET_COLD, + GRUB_EFI_RESET_WARM, + GRUB_EFI_RESET_SHUTDOWN + }; +typedef enum grub_efi_reset_type grub_efi_reset_type_t; + +/* Types. */ +typedef char grub_efi_boolean_t; +typedef long grub_efi_intn_t; +typedef unsigned long grub_efi_uintn_t; +typedef grub_int8_t grub_efi_int8_t; +typedef grub_uint8_t grub_efi_uint8_t; +typedef grub_int16_t grub_efi_int16_t; +typedef grub_uint16_t grub_efi_uint16_t; +typedef grub_int32_t grub_efi_int32_t; +typedef grub_uint32_t grub_efi_uint32_t; +typedef grub_int64_t grub_efi_int64_t; +typedef grub_uint64_t grub_efi_uint64_t; +typedef grub_uint8_t grub_efi_char8_t; +typedef grub_uint16_t grub_efi_char16_t; + +typedef grub_efi_intn_t grub_efi_status_t; + +#define GRUB_EFI_ERROR_CODE(value) \ + ((1L << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) + +#define GRUB_EFI_WARNING_CODE(value) (value) + +#define GRUB_EFI_SUCCESS 0 + +#define GRUB_EFI_LOAD_ERROR GRUB_EFI_ERROR_CODE (1) +#define GRUB_EFI_INVALID_PARAMETER GRUB_EFI_ERROR_CODE (2) +#define GRUB_EFI_UNSUPPORTED GRUB_EFI_ERROR_CODE (3) +#define GRUB_EFI_BAD_BUFFER_SIZE GRUB_EFI_ERROR_CODE (4) +#define GRUB_EFI_BUFFER_TOO_SMALL GRUB_EFI_ERROR_CODE (5) +#define GRUB_EFI_NOT_READY GRUB_EFI_ERROR_CODE (6) +#define GRUB_EFI_DEVICE_ERROR GRUB_EFI_ERROR_CODE (7) +#define GRUB_EFI_WRITE_PROTECTED GRUB_EFI_ERROR_CODE (8) +#define GRUB_EFI_OUT_OF_RESOURCES GRUB_EFI_ERROR_CODE (9) +#define GRUB_EFI_VOLUME_CORRUPTED GRUB_EFI_ERROR_CODE (10) +#define GRUB_EFI_VOLUME_FULL GRUB_EFI_ERROR_CODE (11) +#define GRUB_EFI_NO_MEDIA GRUB_EFI_ERROR_CODE (12) +#define GRUB_EFI_MEDIA_CHANGED GRUB_EFI_ERROR_CODE (13) +#define GRUB_EFI_NOT_FOUND GRUB_EFI_ERROR_CODE (14) +#define GRUB_EFI_ACCESS_DENIED GRUB_EFI_ERROR_CODE (15) +#define GRUB_EFI_NO_RESPONSE GRUB_EFI_ERROR_CODE (16) +#define GRUB_EFI_NO_MAPPING GRUB_EFI_ERROR_CODE (17) +#define GRUB_EFI_TIMEOUT GRUB_EFI_ERROR_CODE (18) +#define GRUB_EFI_NOT_STARTED GRUB_EFI_ERROR_CODE (19) +#define GRUB_EFI_ALREADY_STARTED GRUB_EFI_ERROR_CODE (20) +#define GRUB_EFI_ABORTED GRUB_EFI_ERROR_CODE (21) +#define GRUB_EFI_ICMP_ERROR GRUB_EFI_ERROR_CODE (22) +#define GRUB_EFI_TFTP_ERROR GRUB_EFI_ERROR_CODE (23) +#define GRUB_EFI_PROTOCOL_ERROR GRUB_EFI_ERROR_CODE (24) +#define GRUB_EFI_INCOMPATIBLE_VERSION GRUB_EFI_ERROR_CODE (25) +#define GRUB_EFI_SECURITY_VIOLATION GRUB_EFI_ERROR_CODE (26) +#define GRUB_EFI_CRC_ERROR GRUB_EFI_ERROR_CODE (27) + +#define GRUB_EFI_WARN_UNKNOWN_GLYPH GRUB_EFI_WARNING_CODE (1) +#define GRUB_EFI_WARN_DELETE_FAILURE GRUB_EFI_WARNING_CODE (2) +#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3) +#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4) + +typedef void *grub_efi_handle_t; +typedef void *grub_efi_event_t; +typedef grub_efi_uint64_t grub_efi_lba_t; +typedef grub_efi_uintn_t grub_efi_tpl_t; +typedef grub_uint8_t grub_efi_mac_address_t[32]; +typedef grub_uint8_t grub_efi_ipv4_address_t[4]; +typedef grub_uint16_t grub_efi_ipv6_address_t[8]; +typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); +typedef grub_efi_uint64_t grub_efi_physical_address_t; +typedef grub_efi_uint64_t grub_efi_virtual_address_t; + +struct grub_efi_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} __attribute__ ((aligned(8))); +typedef struct grub_efi_guid grub_efi_guid_t; + +/* XXX although the spec does not specify the padding, this actually + must have the padding! */ +struct grub_efi_memory_descriptor +{ + grub_efi_uint32_t type; + grub_efi_uint32_t padding; + grub_efi_physical_address_t physical_start; + grub_efi_virtual_address_t virtual_start; + grub_efi_uint64_t num_pages; + grub_efi_uint64_t attribute; +}; +typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t; + +/* Device Path definitions. */ +struct grub_efi_device_path +{ + grub_efi_uint8_t type; + grub_efi_uint8_t subtype; + grub_efi_uint8_t length[2]; +}; +typedef struct grub_efi_device_path grub_efi_device_path_t; +/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it. + It seems to be identical to EFI_DEVICE_PATH. */ +typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; + +#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f) +#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype) +#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) \ + ((dp)->length[0] | ((grub_efi_uint16_t) ((dp)->length[1]) << 8)) + +/* The End of Device Path nodes. */ +#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f) + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01 + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \ + (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \ + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \ + == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)) + +#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \ + ((grub_efi_device_path_t *) ((char *) (dp) \ + + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) + +/* Hardware Device Path. */ +#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 + +#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_pci_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; + grub_efi_uint8_t device; +}; +typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t; + +#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_pccard_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; +}; +typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; + +#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_memory_mapped_device_path +{ + grub_efi_device_path_t header; + grub_efi_memory_type_t memory_type; + grub_efi_physical_address_t start_address; + grub_efi_physical_address_t end_address; +}; +typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t; + +#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_vendor_device_path +{ + grub_efi_device_path_t header; + grub_efi_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +}; +typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t; + +#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_controller_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t controller_number; +}; +typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t; + +/* ACPI Device Path. */ +#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2 + +#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; +}; +typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_expanded_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; + grub_efi_uint32_t cid; + char hidstr[1]; +}; +typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr) +#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1) +#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1) + +/* Messaging Device Path. */ +#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3 + +#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_atapi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t primary_secondary; + grub_efi_uint8_t slave_master; + grub_efi_uint16_t lun; +}; +typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t; + +#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_scsi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t pun; + grub_efi_uint16_t lun; +}; +typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t; + +#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_fibre_channel_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t wwn; + grub_efi_uint64_t lun; +}; +typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t; + +#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_1394_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t guid; +}; +typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t; + +#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_usb_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t parent_port_number; + grub_efi_uint8_t interface; +}; +typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t; + +#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15 + +struct grub_efi_usb_class_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t vendor_id; + grub_efi_uint16_t product_id; + grub_efi_uint8_t device_class; + grub_efi_uint8_t device_subclass; + grub_efi_uint8_t device_protocol; +}; +typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t; + +#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6 + +struct grub_efi_i2o_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t tid; +}; +typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t; + +#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11 + +struct grub_efi_mac_address_device_path +{ + grub_efi_device_path_t header; + grub_efi_mac_address_t mac_address; + grub_efi_uint8_t if_type; +}; +typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t; + +#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12 + +struct grub_efi_ipv4_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv4_address_t local_ip_address; + grub_efi_ipv4_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +}; +typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; + +#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13 + +struct grub_efi_ipv6_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv6_address_t local_ip_address; + grub_efi_ipv6_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +}; +typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; + +#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9 + +struct grub_efi_infiniband_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t resource_flags; + grub_efi_uint8_t port_gid[16]; + grub_efi_uint64_t remote_id; + grub_efi_uint64_t target_port_id; + grub_efi_uint64_t device_id; +}; +typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t; + +#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14 + +struct grub_efi_uart_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t baud_rate; + grub_efi_uint8_t data_bits; + grub_efi_uint8_t parity; + grub_efi_uint8_t stop_bits; +}; +typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t; + +#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 + +struct grub_efi_vendor_messaging_device_path +{ + grub_efi_device_path_t header; + grub_efi_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +}; +typedef struct grub_efi_vendor_messaging_device_path grub_efi_vendor_messaging_device_path_t; + +/* Media Device Path. */ +#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4 + +#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_hard_drive_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t partition_number; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; + grub_efi_uint8_t partition_signature[8]; + grub_efi_uint8_t mbr_type; + grub_efi_uint8_t signature_type; +}; +typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t; + +#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_cdrom_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t boot_entry; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; +}; +typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; + +#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_vendor_media_device_path +{ + grub_efi_device_path_t header; + grub_efi_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +}; +typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t; + +#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_file_path_device_path +{ + grub_efi_device_path_t header; + grub_efi_char16_t path_name[0]; +}; +typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; + +#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_protocol_device_path +{ + grub_efi_device_path_t header; + grub_efi_guid_t guid; +}; +typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; + +/* BIOS Boot Specification Device Path. */ +#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5 + +#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_bios_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t device_type; + grub_efi_uint16_t status_flags; + char description[0]; +}; +typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; + +struct grub_efi_open_protocol_information_entry +{ + grub_efi_handle_t agent_handle; + grub_efi_handle_t controller_handle; + grub_efi_uint32_t attributes; + grub_efi_uint32_t open_count; +}; +typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t; + +struct grub_efi_time +{ + grub_efi_uint16_t year; + grub_efi_uint8_t month; + grub_efi_uint8_t day; + grub_efi_uint8_t hour; + grub_efi_uint8_t minute; + grub_efi_uint8_t second; + grub_efi_uint8_t pad1; + grub_efi_uint32_t nanosecond; + grub_efi_int16_t time_zone; + grub_efi_uint8_t daylight; + grub_efi_uint8_t pad2; +}; +typedef struct grub_efi_time grub_efi_time_t; + +struct grub_efi_time_capabilities +{ + grub_efi_uint32_t resolution; + grub_efi_uint32_t accuracy; + grub_efi_boolean_t sets_to_zero; +}; +typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t; + +struct grub_efi_input_key +{ + grub_efi_uint16_t scan_code; + grub_efi_char16_t unicode_char; +}; +typedef struct grub_efi_input_key grub_efi_input_key_t; + +struct grub_efi_simple_text_output_mode +{ + grub_efi_int32_t max_mode; + grub_efi_int32_t mode; + grub_efi_int32_t attribute; + grub_efi_int32_t cursor_column; + grub_efi_int32_t cursor_row; + grub_efi_boolean_t cursor_visible; +}; +typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t; + +/* Tables. */ +struct grub_efi_table_header +{ + grub_efi_uint64_t signature; + grub_efi_uint32_t revision; + grub_efi_uint32_t header_size; + grub_efi_uint32_t crc32; + grub_efi_uint32_t reserved; +}; +typedef struct grub_efi_table_header grub_efi_table_header_t; + +struct grub_efi_boot_services +{ + grub_efi_table_header_t hdr; + + grub_efi_tpl_t + (*raise_tpl) (grub_efi_tpl_t new_tpl); + + void + (*restore_tpl) (grub_efi_tpl_t old_tpl); + + grub_efi_status_t + (*allocate_pages) (grub_efi_allocate_type_t type, + grub_efi_memory_type_t memory_type, + grub_efi_uintn_t pages, + grub_efi_physical_address_t *memory); + + grub_efi_status_t + (*free_pages) (grub_efi_physical_address_t memory, + grub_efi_uintn_t pages); + + grub_efi_status_t + (*get_memory_map) (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version); + + grub_efi_status_t + (*allocate_pool) (grub_efi_memory_type_t pool_type, + grub_efi_uintn_t size, + void **buffer); + + grub_efi_status_t + (*free_pool) (void *buffer); + + grub_efi_status_t + (*create_event) (grub_efi_uint32_t type, + grub_efi_tpl_t notify_tpl, + void (*notify_function) (grub_efi_event_t event, + void *context), + void *notify_context, + grub_efi_event_t *event); + + grub_efi_status_t + (*set_timer) (grub_efi_event_t event, + grub_efi_timer_delay_t type, + grub_efi_uint64_t trigger_time); + + grub_efi_status_t + (*wait_for_event) (grub_efi_uintn_t num_events, + grub_efi_event_t *event, + grub_efi_uintn_t *index); + + grub_efi_status_t + (*signal_event) (grub_efi_event_t event); + + grub_efi_status_t + (*close_event) (grub_efi_event_t event); + + grub_efi_status_t + (*check_event) (grub_efi_event_t event); + + grub_efi_status_t + (*install_protocol_interface) (grub_efi_handle_t *handle, + grub_efi_guid_t *protocol, + grub_efi_interface_type_t interface_type, + void *interface); + + grub_efi_status_t + (*reinstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *old_interface, + void *new_interface); + + grub_efi_status_t + (*uninstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *interface); + + grub_efi_status_t + (*handle_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **interface); + + void *reserved; + + grub_efi_status_t + (*register_protocol_notify) (grub_efi_guid_t *protocol, + grub_efi_event_t event, + void **registration); + + grub_efi_status_t + (*locate_handle) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *buffer_size, + grub_efi_handle_t *buffer); + + grub_efi_status_t + (*locate_device_path) (grub_efi_guid_t *protocol, + grub_efi_device_path_t **device_path, + grub_efi_handle_t *device); + + grub_efi_status_t + (*install_configuration_table) (grub_efi_guid_t *guid, void *table); + + grub_efi_status_t + (*load_image) (grub_efi_boolean_t boot_policy, + grub_efi_handle_t parent_image_handle, + grub_efi_device_path_t *file_path, + void *source_buffer, + grub_efi_uintn_t source_size, + grub_efi_handle_t *image_handle); + + grub_efi_status_t + (*start_image) (grub_efi_handle_t image_handle, + grub_efi_uintn_t *exit_data_size, + grub_efi_char16_t **exit_data); + + grub_efi_status_t + (*exit) (grub_efi_handle_t image_handle, + grub_efi_status_t exit_status, + grub_efi_uintn_t exit_data_size, + grub_efi_char16_t *exit_data) __attribute__((noreturn)); + + grub_efi_status_t + (*unload_image) (grub_efi_handle_t image_handle); + + grub_efi_status_t + (*exit_boot_services) (grub_efi_handle_t image_handle, + grub_efi_uintn_t map_key); + + grub_efi_status_t + (*get_next_monotonic_count) (grub_efi_uint64_t *count); + + grub_efi_status_t + (*stall) (grub_efi_uintn_t microseconds); + + grub_efi_status_t + (*set_watchdog_timer) (grub_efi_uintn_t timeout, + grub_efi_uint64_t watchdog_code, + grub_efi_uintn_t data_size, + grub_efi_char16_t *watchdog_data); + + grub_efi_status_t + (*connect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t *driver_image_handle, + grub_efi_device_path_protocol_t *remaining_device_path, + grub_efi_boolean_t recursive); + + grub_efi_status_t + (*disconnect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t driver_image_handle, + grub_efi_handle_t child_handle); + + grub_efi_status_t + (*open_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **interface, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle, + grub_efi_uint32_t attributes); + + grub_efi_status_t + (*close_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle); + + grub_efi_status_t + (*open_protocol_information) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_open_protocol_information_entry_t **entry_buffer, + grub_efi_uintn_t *entry_count); + + grub_efi_status_t + (*protocols_per_handle) (grub_efi_handle_t handle, + grub_efi_guid_t ***protocol_buffer, + grub_efi_uintn_t *protocol_buffer_count); + + grub_efi_status_t + (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *no_handles, + grub_efi_handle_t **buffer); + + grub_efi_status_t + (*locate_protocol) (grub_efi_guid_t *protocol, + void *registration, + void **interface); + + grub_efi_status_t + (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); + + grub_efi_status_t + (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); + + grub_efi_status_t + (*calculate_crc32) (void *data, + grub_efi_uintn_t data_size, + grub_efi_uint32_t *crc32); + + void + (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length); + + void + (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value); +}; +typedef struct grub_efi_boot_services grub_efi_boot_services_t; + +struct grub_efi_runtime_services +{ + grub_efi_table_header_t hdr; + + grub_efi_status_t + (*get_time) (grub_efi_time_t *time, + grub_efi_time_capabilities_t *capabilities); + + grub_efi_status_t + (*set_time) (grub_efi_time_t *time); + + grub_efi_status_t + (*get_wakeup_time) (grub_efi_boolean_t *enabled, + grub_efi_boolean_t *pending, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_wakeup_time) (grub_efi_boolean_t enabled, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); + + grub_efi_status_t + (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); + + grub_efi_status_t + (*get_variable) (grub_efi_char16_t *variable_name, + grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t *attributes, + grub_efi_uintn_t *data_size, + void *data); + + grub_efi_status_t + (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size, + grub_efi_char16_t *variable_name, + grub_efi_guid_t *vendor_guid); + + grub_efi_status_t + (*set_variable) (grub_efi_char16_t *variable_name, + grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t attributes, + grub_efi_uintn_t data_size, + void *data); + + grub_efi_status_t + (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); + + void + (*reset_system) (grub_efi_reset_type_t reset_type, + grub_efi_status_t reset_status, + grub_efi_uintn_t data_size, + grub_efi_char16_t *reset_data); +}; +typedef struct grub_efi_runtime_services grub_efi_runtime_services_t; + +struct grub_efi_configuration_table +{ + grub_efi_guid_t vendor_guid; + void *vendor_table; +}; +typedef struct grub_efi_configuration_table grub_efi_configuration_table_t; + +struct grub_efi_simple_input_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_input_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*read_key_stroke) (struct grub_efi_simple_input_interface *this, + grub_efi_input_key_t *key); + + grub_efi_event_t wait_for_key; +}; +typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t; + +struct grub_efi_simple_text_output_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*output_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*test_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*query_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number, + grub_efi_uintn_t *columns, + grub_efi_uintn_t *rows); + + grub_efi_status_t + (*set_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number); + + grub_efi_status_t + (*set_attributes) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t attribute); + + grub_efi_status_t + (*clear_screen) (struct grub_efi_simple_text_output_interface *this); + + grub_efi_status_t + (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t column, + grub_efi_uintn_t row); + + grub_efi_status_t + (*enable_cursor) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t visible); + + grub_efi_simple_text_output_mode_t *mode; +}; +typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; + +#define GRUB_EFI_BLACK 0x00 +#define GRUB_EFI_BLUE 0x01 +#define GRUB_EFI_GREEN 0x02 +#define GRUB_EFI_CYAN 0x03 +#define GRUB_EFI_RED 0x04 +#define GRUB_EFI_MAGENTA 0x05 +#define GRUB_EFI_BROWN 0x06 +#define GRUB_EFI_LIGHTGRAY 0x07 +#define GRUB_EFI_BRIGHT 0x08 +#define GRUB_EFI_DARKGRAY 0x08 +#define GRUB_EFI_LIGHTBLUE 0x09 +#define GRUB_EFI_LIGHTGREEN 0x0A +#define GRUB_EFI_LIGHTCYAN 0x0B +#define GRUB_EFI_LIGHTRED 0x0C +#define GRUB_EFI_LIGHTMAGENTA 0x0D +#define GRUB_EFI_YELLOW 0x0E +#define GRUB_EFI_WHITE 0x0F + +#define GRUB_EFI_BACKGROUND_BLACK 0x00 +#define GRUB_EFI_BACKGROUND_BLUE 0x10 +#define GRUB_EFI_BACKGROUND_GREEN 0x20 +#define GRUB_EFI_BACKGROUND_CYAN 0x30 +#define GRUB_EFI_BACKGROUND_RED 0x40 +#define GRUB_EFI_BACKGROUND_MAGENTA 0x50 +#define GRUB_EFI_BACKGROUND_BROWN 0x60 +#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70 + +#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg))) + +struct grub_efi_system_table +{ + grub_efi_table_header_t hdr; + grub_efi_char16_t *firmware_vendor; + grub_efi_uint32_t firmware_revision; + grub_efi_handle_t console_in_handler; + grub_efi_simple_input_interface_t *con_in; + grub_efi_handle_t console_out_handler; + grub_efi_simple_text_output_interface_t *con_out; + grub_efi_handle_t standard_error_handle; + grub_efi_simple_text_output_interface_t *std_err; + grub_efi_runtime_services_t *runtime_services; + grub_efi_boot_services_t *boot_services; + grub_efi_uintn_t num_table_entries; + grub_efi_configuration_table_t *configuration_table; +}; +typedef struct grub_efi_system_table grub_efi_system_table_t; + +struct grub_efi_loaded_image +{ + grub_efi_uint32_t revision; + grub_efi_handle_t parent_handle; + grub_efi_system_table_t *system_table; + + grub_efi_handle_t device_handle; + grub_efi_device_path_t *file_path; + void *reserved; + + grub_efi_uint32_t load_options_size; + void *load_options; + + void *image_base; + grub_efi_uint64_t image_size; + grub_efi_memory_type_t image_code_type; + grub_efi_memory_type_t image_data_type; + + grub_efi_status_t (*unload) (grub_efi_handle_t image_handle); +}; +typedef struct grub_efi_loaded_image grub_efi_loaded_image_t; + +struct grub_efi_disk_io +{ + grub_efi_uint64_t revision; + grub_efi_status_t (*read) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); +}; +typedef struct grub_efi_disk_io grub_efi_disk_io_t; + +struct grub_efi_block_io_media +{ + grub_efi_uint32_t media_id; + grub_efi_boolean_t removable_media; + grub_efi_boolean_t media_present; + grub_efi_boolean_t logical_partition; + grub_efi_boolean_t read_only; + grub_efi_boolean_t write_caching; + grub_efi_uint8_t pad[3]; + grub_efi_uint32_t block_size; + grub_efi_uint32_t io_align; + grub_efi_uint8_t pad2[4]; + grub_efi_lba_t last_block; +}; +typedef struct grub_efi_block_io_media grub_efi_block_io_media_t; + +struct grub_efi_block_io +{ + grub_efi_uint64_t revision; + grub_efi_block_io_media_t *media; + grub_efi_status_t (*reset) (struct grub_efi_block_io *this, + grub_efi_boolean_t extended_verification); + grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this); +}; +typedef struct grub_efi_block_io grub_efi_block_io_t; + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + +#define efi_call_0(func) func() +#define efi_call_1(func, a) func(a) +#define efi_call_2(func, a, b) func(a, b) +#define efi_call_3(func, a, b, c) func(a, b, c) +#define efi_call_4(func, a, b, c, d) func(a, b, c, d) +#define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e) +#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f) + +#else + +#define efi_call_0(func) efi_wrap_0(func) +#define efi_call_1(func, a) efi_wrap_1(func, (grub_uint64_t) a) +#define efi_call_2(func, a, b) efi_wrap_2(func, (grub_uint64_t) a, (grub_uint64_t) b) +#define efi_call_3(func, a, b, c) efi_wrap_3(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c) +#define efi_call_4(func, a, b, c, d) efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, (grub_uint64_t) d) +#define efi_call_5(func, a, b, c, d, e) efi_wrap_5(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, (grub_uint64_t) d, (grub_uint64_t) e) +#define efi_call_6(func, a, b, c, d, e, f) efi_wrap_6(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, (grub_uint64_t) d, (grub_uint64_t) e, (grub_uint64_t) f) + +grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); +grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); +grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2); +grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3); +grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4); +grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5); +grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6); +#endif + +#endif /* ! GRUB_EFI_API_HEADER */ diff --git a/include/grub/efi/chainloader.h b/include/grub/efi/chainloader.h new file mode 100644 index 0000000..d5c11e3 --- /dev/null +++ b/include/grub/efi/chainloader.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_CHAINLOADER_HEADER +#define GRUB_EFI_CHAINLOADER_HEADER 1 + +void grub_rescue_cmd_chainloader (int argc, char *argv[]); + +#endif /* ! GRUB_EFI_CHAINLOADER_HEADER */ diff --git a/include/grub/efi/console.h b/include/grub/efi/console.h new file mode 100644 index 0000000..f90b5b7 --- /dev/null +++ b/include/grub/efi/console.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_CONSOLE_HEADER +#define GRUB_EFI_CONSOLE_HEADER 1 + +#include +#include + +/* Initialize the console system. */ +void grub_console_init (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif /* ! GRUB_EFI_CONSOLE_HEADER */ diff --git a/include/grub/efi/console_control.h b/include/grub/efi/console_control.h new file mode 100644 index 0000000..7c358fc --- /dev/null +++ b/include/grub/efi/console_control.h @@ -0,0 +1,57 @@ +/* console_control.h - definitions of the console control protocol */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* The console control protocol is not a part of the EFI spec, + but defined in Intel's Sample Implementation. */ + +#ifndef GRUB_EFI_CONSOLE_CONTROL_HEADER +#define GRUB_EFI_CONSOLE_CONTROL_HEADER 1 + +#define GRUB_EFI_CONSOLE_CONTROL_GUID \ + { 0xf42f7782, 0x12e, 0x4c12, \ + { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } \ + } + +enum grub_efi_screen_mode + { + GRUB_EFI_SCREEN_TEXT, + GRUB_EFI_SCREEN_GRAPHICS, + GRUB_EFI_SCREEN_TEXT_MAX_VALUE + }; +typedef enum grub_efi_screen_mode grub_efi_screen_mode_t; + +struct grub_efi_console_control_protocol +{ + grub_efi_status_t + (*get_mode) (struct grub_efi_console_control_protocol *this, + grub_efi_screen_mode_t *mode, + grub_efi_boolean_t *uga_exists, + grub_efi_boolean_t *std_in_locked); + + grub_efi_status_t + (*set_mode) (struct grub_efi_console_control_protocol *this, + grub_efi_screen_mode_t mode); + + grub_efi_status_t + (*lock_std_in) (struct grub_efi_console_control_protocol *this, + grub_efi_char16_t *password); +}; +typedef struct grub_efi_console_control_protocol grub_efi_console_control_protocol_t; + +#endif /* ! GRUB_EFI_CONSOLE_CONTROL_HEADER */ diff --git a/include/grub/efi/disk.h b/include/grub/efi/disk.h new file mode 100644 index 0000000..254475c --- /dev/null +++ b/include/grub/efi/disk.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_DISK_HEADER +#define GRUB_EFI_DISK_HEADER 1 + +#include +#include +#include + +grub_efi_handle_t +EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk); +char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle); + +void grub_efidisk_init (void); +void grub_efidisk_fini (void); + +#endif /* ! GRUB_EFI_DISK_HEADER */ diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h new file mode 100644 index 0000000..8c277c0 --- /dev/null +++ b/include/grub/efi/efi.h @@ -0,0 +1,70 @@ +/* efi.h - declare variables and functions for EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_EFI_HEADER +#define GRUB_EFI_EFI_HEADER 1 + +#include +#include +#include + +/* Functions. */ +void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, + void *registration); +grub_efi_handle_t * +EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *num_handles); +void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_uint32_t attributes); +int EXPORT_FUNC(grub_efi_set_text_mode) (int on); +void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); +void * +EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); +int +EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version); +grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); +void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); +char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); +grub_efi_device_path_t * +EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle); +int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key); +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +void grub_efi_mm_init (void); +void grub_efi_mm_fini (void); +void grub_efi_init (void); +void grub_efi_fini (void); +void grub_efi_set_prefix (void); + +/* Variables. */ +extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); +extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); + +#endif /* ! GRUB_EFI_EFI_HEADER */ diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h new file mode 100644 index 0000000..50b4102 --- /dev/null +++ b/include/grub/efi/pe32.h @@ -0,0 +1,267 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_PE32_HEADER +#define GRUB_EFI_PE32_HEADER 1 + +#include + +/* The MSDOS compatibility stub. This was copied from the output of + objcopy, and it is not necessary to care about what this means. */ +#define GRUB_PE32_MSDOS_STUB \ + { \ + 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \ + 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \ + 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \ + 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \ + 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \ + 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \ + 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \ + 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \ + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + } + +#define GRUB_PE32_MSDOS_STUB_SIZE 0x80 + +/* According to the spec, the minimal alignment is 512 bytes... + But some examples (such as EFI drivers in the Intel + Sample Implementation) use 32 bytes (0x20) instead, and it seems + to be working. For now, GRUB uses 512 bytes for safety. */ +#define GRUB_PE32_SECTION_ALIGNMENT 0x200 +#define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT + +struct grub_pe32_coff_header +{ + grub_uint16_t machine; + grub_uint16_t num_sections; + grub_uint32_t time; + grub_uint32_t symtab_offset; + grub_uint32_t num_symbols; + grub_uint16_t optional_header_size; + grub_uint16_t characteristics; +}; + +#define GRUB_PE32_MACHINE_I386 0x14c +#define GRUB_PE32_MACHINE_X86_64 0x8664 + +#define GRUB_PE32_RELOCS_STRIPPED 0x0001 +#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 +#define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004 +#define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008 +#define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010 +#define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020 +#define GRUB_PE32_16BIT_MACHINE 0x0040 +#define GRUB_PE32_BYTES_REVERSED_LO 0x0080 +#define GRUB_PE32_32BIT_MACHINE 0x0100 +#define GRUB_PE32_DEBUG_STRIPPED 0x0200 +#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define GRUB_PE32_SYSTEM 0x1000 +#define GRUB_PE32_DLL 0x2000 +#define GRUB_PE32_UP_SYSTEM_ONLY 0x4000 +#define GRUB_PE32_BYTES_REVERSED_HI 0x8000 + +struct grub_pe32_data_directory +{ + grub_uint32_t rva; + grub_uint32_t size; +}; + +struct grub_pe32_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + grub_uint32_t data_base; + grub_uint32_t image_base; +#else + grub_uint64_t image_base; +#endif + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + + grub_uint32_t stack_reserve_size; + grub_uint32_t stack_commit_size; + grub_uint32_t heap_reserve_size; + grub_uint32_t heap_commit_size; + +#else + + grub_uint64_t stack_reserve_size; + grub_uint64_t stack_commit_size; + grub_uint64_t heap_reserve_size; + grub_uint64_t heap_commit_size; + +#endif + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + +#define GRUB_PE32_PE32_MAGIC 0x10b + +#else + +#define GRUB_PE32_PE32_MAGIC 0x20b + +#endif + +#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 + +#define GRUB_PE32_NUM_DATA_DIRECTORIES 16 + +struct grub_pe32_section_table +{ + char name[8]; + grub_uint32_t virtual_size; + grub_uint32_t virtual_address; + grub_uint32_t raw_data_size; + grub_uint32_t raw_data_offset; + grub_uint32_t relocations_offset; + grub_uint32_t line_numbers_offset; + grub_uint16_t num_relocations; + grub_uint16_t num_line_numbers; + grub_uint32_t characteristics; +}; + +#define GRUB_PE32_SCN_CNT_CODE 0x00000020 +#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 +#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 +#define GRUB_PE32_SCN_MEM_READ 0x40000000 +#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 + +#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000 +#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000 +#define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000 +#define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000 +#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000 +#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000 +#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000 + +#define GRUB_PE32_SCN_ALIGN_SHIFT 20 +#define GRUB_PE32_SCN_ALIGN_MASK 7 + + +struct grub_pe32_header +{ + /* This should be filled in with GRUB_PE32_MSDOS_STUB. */ + grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; + + /* This is always PE\0\0. */ + char signature[4]; + + /* The COFF file header. */ + struct grub_pe32_coff_header coff_header; + + /* The Optional header. */ + struct grub_pe32_optional_header optional_header; +}; + +struct grub_pe32_fixup_block +{ + grub_uint32_t page_rva; + grub_uint32_t block_size; + grub_uint16_t entries[0]; +}; + +#define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset)) + +#define GRUB_PE32_REL_BASED_ABSOLUTE 0 +#define GRUB_PE32_REL_BASED_HIGHLOW 3 + +struct grub_pe32_symbol +{ + union + { + char short_name[8]; + grub_uint32_t long_name[2]; + }; + + grub_uint32_t value; + grub_uint16_t section; + grub_uint16_t type; + grub_uint8_t storage_class; + grub_uint8_t num_aux; +} __attribute__ ((packed)); + +#define GRUB_PE32_SYM_CLASS_EXTERNAL 2 +#define GRUB_PE32_SYM_CLASS_STATIC 3 +#define GRUB_PE32_SYM_CLASS_FILE 0x67 + +#define GRUB_PE32_DT_FUNCTION 0x20 + +struct grub_pe32_reloc +{ + grub_uint32_t offset; + grub_uint32_t symtab_index; + grub_uint16_t type; +} __attribute__ ((packed)); + +#define GRUB_PE32_REL_I386_DIR32 0x6 +#define GRUB_PE32_REL_I386_REL32 0x14 + +#endif /* ! GRUB_EFI_PE32_HEADER */ diff --git a/include/grub/efi/time.h b/include/grub/efi/time.h new file mode 100644 index 0000000..540f6fc --- /dev/null +++ b/include/grub/efi/time.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_TIME_HEADER +#define GRUB_EFI_TIME_HEADER 1 + +#include + +/* This is destined to overflow when one hour passes by. */ +#define GRUB_TICKS_PER_SECOND ((1UL << 31) / 60 / 60 * 2) + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +#endif /* ! GRUB_EFI_TIME_HEADER */ diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h new file mode 100644 index 0000000..9350430 --- /dev/null +++ b/include/grub/efi/uga_draw.h @@ -0,0 +1,76 @@ +/* uga_draw.h - definitions of the uga draw protocol */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* The console control protocol is not a part of the EFI spec, + but defined in Intel's Sample Implementation. */ + +#ifndef GRUB_EFI_UGA_DRAW_HEADER +#define GRUB_EFI_UGA_DRAW_HEADER 1 + +#define GRUB_EFI_UGA_DRAW_GUID \ + { 0x982c298b, 0xf4fa, 0x41cb, { 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 }} + +enum grub_efi_uga_blt_operation +{ + GRUB_EFI_UGA_VIDEO_FILL, + GRUB_EFI_UGA_VIDEO_TO_BLT, + GRUB_EFI_UGA_BLT_TO_VIDEO, + GRUB_EFI_UGA_VIDEO_TO_VIDEO, + GRUB_EFI_UGA_GLT_MAX +}; + +struct grub_efi_uga_pixel +{ + grub_uint8_t Blue; + grub_uint8_t Green; + grub_uint8_t Red; + grub_uint8_t Reserved; +}; + +struct grub_efi_uga_draw_protocol +{ + grub_efi_status_t + (*get_mode) (struct grub_efi_uga_draw_protocol *this, + grub_uint32_t *width, + grub_uint32_t *height, + grub_uint32_t *depth, + grub_uint32_t *refresh_rate); + + grub_efi_status_t + (*set_mode) (struct grub_efi_uga_draw_protocol *this, + grub_uint32_t width, + grub_uint32_t height, + grub_uint32_t depth, + grub_uint32_t refresh_rate); + + grub_efi_status_t + (*blt) (struct grub_efi_uga_draw_protocol *this, + struct grub_efi_uga_pixel *blt_buffer, + enum grub_efi_uga_blt_operation blt_operation, + grub_efi_uintn_t src_x, + grub_efi_uintn_t src_y, + grub_efi_uintn_t dest_x, + grub_efi_uintn_t dest_y, + grub_efi_uintn_t width, + grub_efi_uintn_t height, + grub_efi_uintn_t delta); +}; +typedef struct grub_efi_uga_draw_protocol grub_efi_uga_draw_protocol_t; + +#endif /* ! GRUB_EFI_UGA_DRAW_HEADER */ diff --git a/include/grub/elf.h b/include/grub/elf.h new file mode 100644 index 0000000..5d46daa --- /dev/null +++ b/include/grub/elf.h @@ -0,0 +1,2333 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-1999, 2000, 2001, 2002,2008 Free Software Foundation, Inc. + This file was part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef GRUB_ELF_H +#define GRUB_ELF_H 1 + +/* Standard ELF types. */ + +#include + +/* Type for a 16-bit quantity. */ +typedef grub_uint16_t Elf32_Half; +typedef grub_uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef grub_uint32_t Elf32_Word; +typedef grub_int32_t Elf32_Sword; +typedef grub_uint32_t Elf64_Word; +typedef grub_int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef grub_uint64_t Elf32_Xword; +typedef grub_int64_t Elf32_Sxword; +typedef grub_uint64_t Elf64_Xword; +typedef grub_int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef grub_uint32_t Elf32_Addr; +typedef grub_uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef grub_uint32_t Elf32_Off; +typedef grub_uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef grub_uint16_t Elf32_Section; +typedef grub_uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_AT19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ +#define STN_ABS 65521 + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 10 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxiliary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + long int a_type; /* Entry type */ + union + { + long int a_val; /* Integer value */ + void *a_ptr; /* Pointer value */ + void (*a_fcn) (void); /* Function pointer value */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored */ + + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define ELF_NOTE_ABI 1 + +/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI + note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_68K_NUM 23 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* Keep this the last entry. */ +#define R_386_NUM 38 + + +/* SUN SPARC specific definitions. */ + +/* x86_64 specific definitions. */ +#define R_X86_64_NONE 0 +#define R_X86_64_64 1 +#define R_X86_64_PC32 2 +#define R_X86_64_GOT32 3 +#define R_X86_64_PLT32 4 +#define R_X86_64_COPY 5 +#define R_X86_64_GLOB_DAT 6 +#define R_X86_64_JUMP_SLOT 7 +#define R_X86_64_RELATIVE 8 +#define R_X86_64_GOTPCREL 9 +#define R_X86_64_32 10 +#define R_X86_64_32S 11 +#define R_X86_64_16 12 +#define R_X86_64_PC16 13 +#define R_X86_64_8 14 +#define R_X86_64_PC8 15 + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +/* Keep this the last entry. */ +#define R_SPARC_NUM 80 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP, primarily for Sparc32. */ + +#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ +#define HWCAP_SPARC_ULTRA3 32 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* The following are non-official names and should not be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +/* Keep this the last entry. */ +#define R_MIPS_NUM 38 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +#define DT_MIPS_NUM 0x32 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 +/* Keep this the last entry. */ +#define R_PPC_NUM 37 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A. */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC. */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A. */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ +/* Keep this the last entry. */ +#define R_PPC64_NUM 67 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_NUM 1 + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 + +/* Additional symbol types for Thumb */ +#define STT_ARM_TFUNC 0xd + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +/* ARM relocs. */ +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_TLS_GD_MOV 152 +#define R_SH_TLS_LDM_MOV 153 +#define R_SH_TLS_LDO_MOV 154 +#define R_SH_TLS_IE_MOV 155 +#define R_SH_TLS_LE_MOV 156 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ + +/* Keep this the last entry. */ +#define R_390_NUM 27 + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define r_x86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ + +#define R_X86_64_NUM 24 + +#endif /* ! GRUB_ELF_H */ diff --git a/include/grub/elfload.h b/include/grub/elfload.h new file mode 100644 index 0000000..5d611da --- /dev/null +++ b/include/grub/elfload.h @@ -0,0 +1,58 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ELFLOAD_HEADER +#define GRUB_ELFLOAD_HEADER 1 + +#include +#include +#include +#include +#include + +struct grub_elf_file +{ + grub_file_t file; + union { + Elf64_Ehdr ehdr64; + Elf32_Ehdr ehdr32; + } ehdr; + void *phdrs; +}; +typedef struct grub_elf_file *grub_elf_t; + +typedef grub_err_t (*grub_elf32_load_hook_t) + (Elf32_Phdr *phdr, grub_addr_t *addr); +typedef grub_err_t (*grub_elf64_load_hook_t) + (Elf64_Phdr *phdr, grub_addr_t *addr); + +grub_elf_t grub_elf_open (const char *); +grub_elf_t grub_elf_file (grub_file_t); +grub_err_t grub_elf_close (grub_elf_t); + +int grub_elf_is_elf32 (grub_elf_t); +grub_size_t grub_elf32_size (grub_elf_t); +grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *, + grub_size_t *); + +int grub_elf_is_elf64 (grub_elf_t); +grub_size_t grub_elf64_size (grub_elf_t); +grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *, + grub_size_t *); + +#endif /* ! GRUB_ELFLOAD_HEADER */ diff --git a/include/grub/env.h b/include/grub/env.h new file mode 100644 index 0000000..36c1e87 --- /dev/null +++ b/include/grub/env.h @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ENV_HEADER +#define GRUB_ENV_HEADER 1 + +#include +#include +#include + +struct grub_env_var; + +typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var, + const char *val); +typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, + const char *val); + +enum grub_env_var_type + { + /* The default variable type which is local in current context. */ + GRUB_ENV_VAR_LOCAL, + + /* The exported type, which is passed to new contexts. */ + GRUB_ENV_VAR_GLOBAL, + + /* The data slot type, which is used to store arbitrary data. */ + GRUB_ENV_VAR_DATA + }; + +struct grub_env_var +{ + char *name; + char *value; + grub_env_read_hook_t read_hook; + grub_env_write_hook_t write_hook; + struct grub_env_var *next; + struct grub_env_var **prevp; + enum grub_env_var_type type; +}; + +grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); +char *EXPORT_FUNC(grub_env_get) (const char *name); +void EXPORT_FUNC(grub_env_unset) (const char *name); +void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var)); +grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, + grub_env_read_hook_t read_hook, + grub_env_write_hook_t write_hook); +grub_err_t EXPORT_FUNC(grub_env_context_open) (void); +grub_err_t EXPORT_FUNC(grub_env_context_close) (void); +grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); + +grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name, + const void *ptr); +void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name); +void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name); + +#endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/err.h b/include/grub/err.h new file mode 100644 index 0000000..3435fb7 --- /dev/null +++ b/include/grub/err.h @@ -0,0 +1,71 @@ +/* err.h - error numbers and prototypes */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ERR_HEADER +#define GRUB_ERR_HEADER 1 + +#include + +typedef enum + { + GRUB_ERR_NONE = 0, + GRUB_ERR_TEST_FAILURE, + GRUB_ERR_BAD_MODULE, + GRUB_ERR_OUT_OF_MEMORY, + GRUB_ERR_BAD_FILE_TYPE, + GRUB_ERR_FILE_NOT_FOUND, + GRUB_ERR_FILE_READ_ERROR, + GRUB_ERR_BAD_FILENAME, + GRUB_ERR_UNKNOWN_FS, + GRUB_ERR_BAD_FS, + GRUB_ERR_BAD_NUMBER, + GRUB_ERR_OUT_OF_RANGE, + GRUB_ERR_UNKNOWN_DEVICE, + GRUB_ERR_BAD_DEVICE, + GRUB_ERR_READ_ERROR, + GRUB_ERR_WRITE_ERROR, + GRUB_ERR_UNKNOWN_COMMAND, + GRUB_ERR_INVALID_COMMAND, + GRUB_ERR_BAD_ARGUMENT, + GRUB_ERR_BAD_PART_TABLE, + GRUB_ERR_UNKNOWN_OS, + GRUB_ERR_BAD_OS, + GRUB_ERR_NO_KERNEL, + GRUB_ERR_BAD_FONT, + GRUB_ERR_NOT_IMPLEMENTED_YET, + GRUB_ERR_SYMLINK_LOOP, + GRUB_ERR_BAD_GZIP_DATA, + GRUB_ERR_MENU, + GRUB_ERR_TIMEOUT, + GRUB_ERR_IO + } +grub_err_t; + +extern grub_err_t EXPORT_VAR(grub_errno); +extern char EXPORT_VAR(grub_errmsg)[]; + +grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...); +void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_error_push) (void); +int EXPORT_FUNC(grub_error_pop) (void); +void EXPORT_FUNC(grub_print_error) (void); +int EXPORT_FUNC(grub_err_printf) (const char *fmt, ...) +__attribute__ ((format (printf, 1, 2))); + +#endif /* ! GRUB_ERR_HEADER */ diff --git a/include/grub/file.h b/include/grub/file.h new file mode 100644 index 0000000..df2e9e4 --- /dev/null +++ b/include/grub/file.h @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FILE_HEADER +#define GRUB_FILE_HEADER 1 + +#include +#include +#include +#include + +/* File description. */ +struct grub_file +{ + /* The underlying device. */ + grub_device_t device; + + /* The underlying filesystem. */ + grub_fs_t fs; + + /* The current offset. */ + grub_off_t offset; + + /* The file size. */ + grub_off_t size; + + /* Filesystem-specific data. */ + void *data; + + /* This is called when a sector is read. Used only for a disk device. */ + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, unsigned length); +}; +typedef struct grub_file *grub_file_t; + +/* Get a device name from NAME. */ +char *EXPORT_FUNC(grub_file_get_device_name) (const char *name); + +grub_file_t EXPORT_FUNC(grub_file_open) (const char *name); +grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, char *buf, + grub_size_t len); +grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset); +grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file); + +static inline grub_off_t +grub_file_size (const grub_file_t file) +{ + return file->size; +} + +static inline grub_off_t +grub_file_tell (const grub_file_t file) +{ + return file->offset; +} + +#endif /* ! GRUB_FILE_HEADER */ diff --git a/include/grub/font.h b/include/grub/font.h new file mode 100644 index 0000000..8a5f3ac --- /dev/null +++ b/include/grub/font.h @@ -0,0 +1,115 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FONT_HEADER +#define GRUB_FONT_HEADER 1 + +#include +#include + +/* Forward declaration of opaque structure grub_font. + Users only pass struct grub_font pointers to the font module functions, + and do not have knowledge of the structure contents. */ +struct grub_font; + +/* Font type used to access font functions. */ +typedef struct grub_font *grub_font_t; + +struct grub_font_node +{ + struct grub_font_node *next; + grub_font_t value; +}; + +/* Global font registry. */ +extern struct grub_font_node *grub_font_list; + +struct grub_font_glyph +{ + /* Reference to the font this glyph belongs to. */ + grub_font_t font; + + /* Glyph bitmap width in pixels. */ + grub_uint16_t width; + + /* Glyph bitmap height in pixels. */ + grub_uint16_t height; + + /* Glyph bitmap x offset in pixels. Add to screen coordinate. */ + grub_int16_t offset_x; + + /* Glyph bitmap y offset in pixels. Subtract from screen coordinate. */ + grub_int16_t offset_y; + + /* Number of pixels to advance to start the next character. */ + grub_uint16_t device_width; + + /* Row-major order, packed bits (no padding; rows can break within a byte). + The length of the array is (width * height + 7) / 8. Within a + byte, the most significant bit is the first (leftmost/uppermost) pixel. + Pixels are coded as bits, value 1 meaning of opaque pixel and 0 is + transparent. If the length of the array does not fit byte boundary, it + will be padded with 0 bits to make it fit. */ + grub_uint8_t bitmap[0]; +}; + +/* Initialize the font loader. + Must be called before any fonts are loaded or used. */ +void grub_font_loader_init (void); + +/* Load a font and add it to the beginning of the global font list. + Returns: 0 upon success; nonzero upon failure. */ +int grub_font_load (const char *filename); + +/* Get the font that has the specified name. Font names are in the form + "Family Name Bold Italic 14", where Bold and Italic are optional. + If no font matches the name specified, the most recently loaded font + is returned as a fallback. */ +grub_font_t grub_font_get (const char *font_name); + +const char *grub_font_get_name (grub_font_t font); + +int grub_font_get_max_char_width (grub_font_t font); + +int grub_font_get_max_char_height (grub_font_t font); + +int grub_font_get_ascent (grub_font_t font); + +int grub_font_get_descent (grub_font_t font); + +int grub_font_get_leading (grub_font_t font); + +int grub_font_get_height (grub_font_t font); + +int grub_font_get_string_width (grub_font_t font, const char *str); + +struct grub_font_glyph *grub_font_get_glyph (grub_font_t font, + grub_uint32_t code); + +struct grub_font_glyph *grub_font_get_glyph_with_fallback (grub_font_t font, + grub_uint32_t code); + +grub_err_t grub_font_draw_glyph (struct grub_font_glyph *glyph, + grub_video_color_t color, + int left_x, int baseline_y); + +grub_err_t grub_font_draw_string (const char *str, grub_font_t font, + grub_video_color_t color, + int left_x, int baseline_y); + +#endif /* ! GRUB_FONT_HEADER */ diff --git a/include/grub/fs.h b/include/grub/fs.h new file mode 100644 index 0000000..46c7492 --- /dev/null +++ b/include/grub/fs.h @@ -0,0 +1,79 @@ +/* fs.h - filesystem manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FS_HEADER +#define GRUB_FS_HEADER 1 + +#include +#include +#include + +/* Forward declaration is required, because of mutual reference. */ +struct grub_file; + +/* Filesystem descriptor. */ +struct grub_fs +{ + /* My name. */ + const char *name; + + /* Call HOOK with each file under DIR. */ + grub_err_t (*dir) (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)); + + /* Open a file named NAME and initialize FILE. */ + grub_err_t (*open) (struct grub_file *file, const char *name); + + /* Read LEN bytes data from FILE into BUF. */ + grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len); + + /* Close the file FILE. */ + grub_err_t (*close) (struct grub_file *file); + + /* Return the label of the device DEVICE in LABEL. The label is + returned in a grub_malloc'ed buffer and should be freed by the + caller. */ + grub_err_t (*label) (grub_device_t device, char **label); + + /* Return the uuid of the device DEVICE in UUID. The uuid is + returned in a grub_malloc'ed buffer and should be freed by the + caller. */ + grub_err_t (*uuid) (grub_device_t device, char **uuid); + + /* The next filesystem. */ + struct grub_fs *next; +}; +typedef struct grub_fs *grub_fs_t; + +/* This is special, because block lists are not files in usual sense. */ +extern struct grub_fs grub_fs_blocklist; + +/* This hook is used to automatically load filesystem modules. + If this hook loads a module, return non-zero. Otherwise return zero. + The newly loaded filesystem is assumed to be inserted into the head of + the linked list GRUB_FS_LIST through the function grub_fs_register. */ +typedef int (*grub_fs_autoload_hook_t) (void); +extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); + +void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs); +void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs); +void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs)); +grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); + +#endif /* ! GRUB_FS_HEADER */ diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h new file mode 100644 index 0000000..7092cac --- /dev/null +++ b/include/grub/fshelp.h @@ -0,0 +1,80 @@ +/* fshelp.h -- Filesystem helper functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FSHELP_HEADER +#define GRUB_FSHELP_HEADER 1 + +#include +#include +#include + +typedef struct grub_fshelp_node *grub_fshelp_node_t; + +#define GRUB_FSHELP_CASE_INSENSITIVE 0x100 + +enum grub_fshelp_filetype + { + GRUB_FSHELP_UNKNOWN, + GRUB_FSHELP_REG, + GRUB_FSHELP_DIR, + GRUB_FSHELP_SYMLINK + }; + +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. Make + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required + because GCC has a nasty bug when using regparm=3. */ +grub_err_t +EXPORT_FUNC(grub_fshelp_find_file) (const char *path, + grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + int (*iterate_dir) (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)), + char *(*read_symlink) (grub_fshelp_node_t node), + enum grub_fshelp_filetype expect); + + +/* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, + beginning with the block POS. READ_HOOK should be set before + reading a block from the file. GET_BLOCK is used to translate file + blocks to disk blocks. The file is FILESIZE bytes big and the + blocks have a size of LOG2BLOCKSIZE (in log2). */ +grub_ssize_t +EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length), + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), + grub_off_t filesize, int log2blocksize); + +unsigned int +EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize, + unsigned int *pow); + +#endif /* ! GRUB_FSHELP_HEADER */ diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h new file mode 100644 index 0000000..0244530 --- /dev/null +++ b/include/grub/gpt_partition.h @@ -0,0 +1,71 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GPT_PARTITION_HEADER +#define GRUB_GPT_PARTITION_HEADER 1 + +#include + +struct grub_gpt_part_type +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} __attribute__ ((aligned(8))); +typedef struct grub_gpt_part_type grub_gpt_part_type_t; + +#define GRUB_GPT_PARTITION_TYPE_EMPTY \ + { 0x0, 0x0, 0x0, \ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \ + } + +#define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ + { grub_cpu_to_le32 (0x21686148), grub_cpu_to_le16 (0x6449), grub_cpu_to_le16 (0x6e6f), \ + { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ + } + +struct grub_gpt_header +{ + grub_uint8_t magic[8]; + grub_uint32_t version; + grub_uint32_t headersize; + grub_uint32_t crc32; + grub_uint32_t unused1; + grub_uint64_t primary; + grub_uint64_t backup; + grub_uint64_t start; + grub_uint64_t end; + grub_uint8_t guid[16]; + grub_uint64_t partitions; + grub_uint32_t maxpart; + grub_uint32_t partentry_size; + grub_uint32_t partentry_crc32; +} __attribute__ ((packed)); + +struct grub_gpt_partentry +{ + grub_gpt_part_type_t type; + grub_uint8_t guid[16]; + grub_uint64_t start; + grub_uint64_t end; + grub_uint8_t attrib; + char name[72]; +} __attribute__ ((packed)); + +#endif /* ! GRUB_GPT_PARTITION_HEADER */ diff --git a/include/grub/gzio.h b/include/grub/gzio.h new file mode 100644 index 0000000..cd7f397 --- /dev/null +++ b/include/grub/gzio.h @@ -0,0 +1,28 @@ +/* gzio.h - prototypes for gzio */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GZIO_H +#define GRUB_GZIO_H 1 + +#include + +grub_file_t grub_gzio_open (grub_file_t io, int transparent); +grub_file_t grub_gzfile_open (const char *name, int transparent); + +#endif /* ! GRUB_GZIO_H */ diff --git a/include/grub/hfs.h b/include/grub/hfs.h new file mode 100644 index 0000000..311b998 --- /dev/null +++ b/include/grub/hfs.h @@ -0,0 +1,60 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_HFS_HEADER +#define GRUB_HFS_HEADER 1 + +#include + +#define GRUB_HFS_MAGIC 0x4244 + +/* A single extent. A file consists of one or more extents. */ +struct grub_hfs_extent +{ + /* The first physical block. */ + grub_uint16_t first_block; + grub_uint16_t count; +}; + +/* HFS stores extents in groups of 3. */ +typedef struct grub_hfs_extent grub_hfs_datarecord_t[3]; + +/* The HFS superblock (The official name is `Master Directory + Block'). */ +struct grub_hfs_sblock +{ + grub_uint16_t magic; + grub_uint8_t unused[18]; + grub_uint32_t blksz; + grub_uint8_t unused2[4]; + grub_uint16_t first_block; + grub_uint8_t unused4[6]; + + /* A pascal style string that holds the volumename. */ + grub_uint8_t volname[28]; + + grub_uint8_t unused5[60]; + grub_uint16_t embed_sig; + struct grub_hfs_extent embed_extent; + grub_uint8_t unused6[4]; + grub_hfs_datarecord_t extent_recs; + grub_uint32_t catalog_size; + grub_hfs_datarecord_t catalog_recs; +} __attribute__ ((packed)); + +#endif /* ! GRUB_HFS_HEADER */ diff --git a/include/grub/i386/at_keyboard.h b/include/grub/i386/at_keyboard.h new file mode 100644 index 0000000..5c15ef3 --- /dev/null +++ b/include/grub/i386/at_keyboard.h @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_AT_KEYBOARD_HEADER +#define GRUB_CPU_AT_KEYBOARD_HEADER 1 + +#include + +#define SHIFT_L 0x2a +#define SHIFT_R 0x36 +#define CTRL 0x1d +#define ALT 0x38 +#define CAPS_LOCK 0x3a + +#define KEYBOARD_REG_DATA 0x60 +#define KEYBOARD_REG_STATUS 0x64 + +/* Used for sending commands to the controller. */ +#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) +#define KEYBOARD_COMMAND_READ 0x20 +#define KEYBOARD_COMMAND_WRITE 0x60 +#define KEYBOARD_COMMAND_REBOOT 0xfe + +#define KEYBOARD_SCANCODE_SET1 0x40 + +#define KEYBOARD_ISMAKE(x) !((x) & 0x80) +#define KEYBOARD_ISREADY(x) (((x) & 0x01) == 0) +#define KEYBOARD_SCANCODE(x) ((x) & 0x7f) + +#ifdef GRUB_MACHINE_IEEE1275 +#define OLPC_UP GRUB_TERM_UP +#define OLPC_DOWN GRUB_TERM_DOWN +#define OLPC_LEFT GRUB_TERM_LEFT +#define OLPC_RIGHT GRUB_TERM_RIGHT +#else +#define OLPC_UP '\0' +#define OLPC_DOWN '\0' +#define OLPC_LEFT '\0' +#define OLPC_RIGHT '\0' +#endif + +#endif diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h new file mode 100644 index 0000000..00296c9 --- /dev/null +++ b/include/grub/i386/bsd.h @@ -0,0 +1,232 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BSD_CPU_HEADER +#define GRUB_BSD_CPU_HEADER 1 + +#include + +#define KERNEL_TYPE_NONE 0 +#define KERNEL_TYPE_FREEBSD 1 +#define KERNEL_TYPE_OPENBSD 2 +#define KERNEL_TYPE_NETBSD 3 + +#define GRUB_BSD_TEMP_BUFFER 0x68000 + +#define FREEBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define FREEBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define FREEBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define FREEBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define FREEBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define FREEBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ +#define FREEBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define FREEBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define FREEBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define FREEBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define FREEBSD_RB_CONFIG (1 << 10) /* invoke user configuration routing */ +#define FREEBSD_RB_VERBOSE (1 << 11) /* print all potentially useful info */ +#define FREEBSD_RB_SERIAL (1 << 12) /* user serial port as console */ +#define FREEBSD_RB_CDROM (1 << 13) /* use cdrom as root */ +#define FREEBSD_RB_GDB (1 << 15) /* use GDB remote debugger instead of DDB */ +#define FREEBSD_RB_MUTE (1 << 16) /* Come up with the console muted */ +#define FREEBSD_RB_PAUSE (1 << 20) +#define FREEBSD_RB_QUIET (1 << 21) +#define FREEBSD_RB_NOINTR (1 << 28) +#define FREENSD_RB_MULTIPLE (1 << 29) /* Use multiple consoles */ +#define FREEBSD_RB_DUAL FREENSD_RB_MULTIPLE +#define FREEBSD_RB_BOOTINFO (1 << 31) /* have `struct bootinfo *' arg */ + +#define FREEBSD_B_DEVMAGIC 0xa0000000 +#define FREEBSD_B_SLICESHIFT 20 +#define FREEBSD_B_UNITSHIFT 16 +#define FREEBSD_B_PARTSHIFT 8 +#define FREEBSD_B_TYPESHIFT 0 + +#define FREEBSD_BOOTINFO_VERSION 1 +#define FREEBSD_N_BIOS_GEOM 8 + +#define FREEBSD_MODINFO_END 0x0000 /* End of list */ +#define FREEBSD_MODINFO_NAME 0x0001 /* Name of module (string) */ +#define FREEBSD_MODINFO_TYPE 0x0002 /* Type of module (string) */ +#define FREEBSD_MODINFO_ADDR 0x0003 /* Loaded address */ +#define FREEBSD_MODINFO_SIZE 0x0004 /* Size of module */ +#define FREEBSD_MODINFO_EMPTY 0x0005 /* Has been deleted */ +#define FREEBSD_MODINFO_ARGS 0x0006 /* Parameters string */ +#define FREEBSD_MODINFO_METADATA 0x8000 /* Module-specfic */ + +#define FREEBSD_MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ +#define FREEBSD_MODINFOMD_ELFHDR 0x0002 /* ELF header */ +#define FREEBSD_MODINFOMD_SSYM 0x0003 /* start of symbols */ +#define FREEBSD_MODINFOMD_ESYM 0x0004 /* end of symbols */ +#define FREEBSD_MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */ +#define FREEBSD_MODINFOMD_ENVP 0x0006 /* envp[] */ +#define FREEBSD_MODINFOMD_HOWTO 0x0007 /* boothowto */ +#define FREEBSD_MODINFOMD_KERNEND 0x0008 /* kernend */ +#define FREEBSD_MODINFOMD_SHDR 0x0009 /* section header table */ +#define FREEBSD_MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ + +#define FREEBSD_MODINFOMD_DEPLIST (0x4001 | FREEBSD_MODINFOMD_NOCOPY) /* depends on */ + +#define FREEBSD_MODTYPE_KERNEL "elf kernel" +#define FREEBSD_MODTYPE_MODULE "elf module" +#define FREEBSD_MODTYPE_RAW "raw" + +struct grub_freebsd_bootinfo +{ + grub_uint32_t bi_version; + grub_uint8_t *bi_kernelname; + struct nfs_diskless *bi_nfs_diskless; + grub_uint32_t bi_n_bios_used; + grub_uint32_t bi_bios_geom[FREEBSD_N_BIOS_GEOM]; + grub_uint32_t bi_size; + grub_uint8_t bi_memsizes_valid; + grub_uint8_t bi_bios_dev; + grub_uint8_t bi_pad[2]; + grub_uint32_t bi_basemem; + grub_uint32_t bi_extmem; + grub_uint32_t bi_symtab; + grub_uint32_t bi_esymtab; + grub_uint32_t bi_kernend; + grub_uint32_t bi_envp; + grub_uint32_t bi_modulep; +} __attribute__ ((packed)); + +#define OPENBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define OPENBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define OPENBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define OPENBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define OPENBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define OPENBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ +#define OPENBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define OPENBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define OPENBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define OPENBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define OPENBSD_RB_CONFIG (1 << 10) /* change configured devices */ +#define OPENBSD_RB_TIMEBAD (1 << 11) /* don't call resettodr() in boot() */ +#define OPENBSD_RB_POWERDOWN (1 << 12) /* attempt to power down machine */ +#define OPENBSD_RB_SERCONS (1 << 13) /* use serial console if available */ +#define OPENBSD_RB_USERREQ (1 << 14) /* boot() called at user request (e.g. ddb) */ + +#define OPENBSD_B_DEVMAGIC 0xa0000000 +#define OPENBSD_B_ADAPTORSHIFT 24 +#define OPENBSD_B_CTRLSHIFT 20 +#define OPENBSD_B_UNITSHIFT 16 +#define OPENBSD_B_PARTSHIFT 8 +#define OPENBSD_B_TYPESHIFT 0 + +#define OPENBSD_BOOTARG_APIVER (OPENBSD_BAPIV_VECTOR | \ + OPENBSD_BAPIV_ENV | \ + OPENBSD_BAPIV_BMEMMAP) + +#define OPENBSD_BAPIV_ANCIENT 0x0 /* MD old i386 bootblocks */ +#define OPENBSD_BAPIV_VARS 0x1 /* MD structure w/ add info passed */ +#define OPENBSD_BAPIV_VECTOR 0x2 /* MI vector of MD structures passed */ +#define OPENBSD_BAPIV_ENV 0x4 /* MI environment vars vector */ +#define OPENBSD_BAPIV_BMEMMAP 0x8 /* MI memory map passed is in bytes */ + +#define OPENBSD_BOOTARG_ENV 0x1000 +#define OPENBSD_BOOTARG_END -1 + +#define OPENBSD_BOOTARG_MMAP 0 + +struct grub_openbsd_bios_mmap +{ + grub_uint64_t addr; + grub_uint64_t len; + grub_uint32_t type; +}; + +struct grub_openbsd_bootargs +{ + int ba_type; + int ba_size; + struct grub_openbsd_bootargs *ba_next; +} __attribute__ ((packed)); + +#define NETBSD_RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#define NETBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define NETBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define NETBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define NETBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define NETBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define NETBSD_RB_UNUSED1 (1 << 5) /* was RB_DFLTROOT, obsolete */ +#define NETBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define NETBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define NETBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define NETBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define NETBSD_RB_STRING (1 << 10) /* use provided bootstr */ +#define NETBSD_RB_POWERDOWN ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */ +#define NETBSD_RB_USERCONFIG (1 << 12) /* change configured devices */ + +#define NETBSD_AB_NORMAL 0 /* boot normally (default) */ + +#define NETBSD_AB_QUIET (1 << 16) /* boot quietly */ +#define NETBSD_AB_VERBOSE (1 << 17) /* boot verbosely */ +#define NETBSD_AB_SILENT (1 << 18) /* boot silently */ +#define NETBSD_AB_DEBUG (1 << 19) /* boot with debug messages */ + +struct grub_netbsd_bootinfo +{ + grub_uint32_t bi_count; + void *bi_data[1]; +}; + +#define NETBSD_BTINFO_BOOTPATH 0 +#define NETBSD_BTINFO_ROOTDEVICE 1 +#define NETBSD_BTINFO_BOOTDISK 3 + +struct grub_netbsd_btinfo_common +{ + int len; + int type; +}; + +struct grub_netbsd_btinfo_bootpath +{ + struct grub_netbsd_btinfo_common common; + char bootpath[80]; +}; + +struct grub_netbsd_btinfo_rootdevice +{ + struct grub_netbsd_btinfo_common common; + char devname[16]; +}; + +struct grub_netbsd_btinfo_bootdisk +{ + struct grub_netbsd_btinfo_common common; + int labelsector; /* label valid if != -1 */ + struct + { + grub_uint16_t type, checksum; + char packname[16]; + } label; + int biosdev; + int partition; +}; + +void grub_rescue_cmd_freebsd (int argc, char *argv[]); +void grub_rescue_cmd_openbsd (int argc, char *argv[]); +void grub_rescue_cmd_netbsd (int argc, char *argv[]); + +void grub_rescue_cmd_freebsd_loadenv (int argc, char *argv[]); +void grub_rescue_cmd_freebsd_module (int argc, char *argv[]); + +#endif /* ! GRUB_BSD_CPU_HEADER */ diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h new file mode 100644 index 0000000..1c0530d --- /dev/null +++ b/include/grub/i386/cmos.h @@ -0,0 +1,74 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_CMOS_H +#define GRUB_CPU_CMOS_H 1 + +#include +#include + +#define GRUB_CMOS_ADDR_REG 0x70 +#define GRUB_CMOS_DATA_REG 0x71 + +#define GRUB_CMOS_INDEX_SECOND 0 +#define GRUB_CMOS_INDEX_SECOND_ALARM 1 +#define GRUB_CMOS_INDEX_MINUTE 2 +#define GRUB_CMOS_INDEX_MINUTE_ALARM 3 +#define GRUB_CMOS_INDEX_HOUR 4 +#define GRUB_CMOS_INDEX_HOUR_ALARM 5 +#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6 +#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7 +#define GRUB_CMOS_INDEX_MONTH 8 +#define GRUB_CMOS_INDEX_YEAR 9 + +#define GRUB_CMOS_INDEX_STATUS_A 0xA +#define GRUB_CMOS_INDEX_STATUS_B 0xB +#define GRUB_CMOS_INDEX_STATUS_C 0xC +#define GRUB_CMOS_INDEX_STATUS_D 0xD + +#define GRUB_CMOS_STATUS_B_DAYLIGHT 1 +#define GRUB_CMOS_STATUS_B_24HOUR 2 +#define GRUB_CMOS_STATUS_B_BINARY 4 + +static inline grub_uint8_t +grub_bcd_to_num (grub_uint8_t a) +{ + return ((a >> 4) * 10 + (a & 0xF)); +} + +static inline grub_uint8_t +grub_num_to_bcd (grub_uint8_t a) +{ + return (((a / 10) << 4) + (a % 10)); +} + +static inline grub_uint8_t +grub_cmos_read (grub_uint8_t index) +{ + grub_outb (index, GRUB_CMOS_ADDR_REG); + return grub_inb (GRUB_CMOS_DATA_REG); +} + +static inline void +grub_cmos_write (grub_uint8_t index, grub_uint8_t value) +{ + grub_outb (index, GRUB_CMOS_ADDR_REG); + grub_outb (value, GRUB_CMOS_DATA_REG); +} + +#endif /* GRUB_CPU_CMOS_H */ diff --git a/include/grub/i386/coreboot/boot.h b/include/grub/i386/coreboot/boot.h new file mode 100644 index 0000000..6cd23aa --- /dev/null +++ b/include/grub/i386/coreboot/boot.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/coreboot/console.h b/include/grub/i386/coreboot/console.h new file mode 100644 index 0000000..305a46d --- /dev/null +++ b/include/grub/i386/coreboot/console.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/coreboot/init.h b/include/grub/i386/coreboot/init.h new file mode 100644 index 0000000..e670074 --- /dev/null +++ b/include/grub/i386/coreboot/init.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_INIT_I386_LINUXBIOS_HEADER +#define GRUB_INIT_I386_LINUXBIOS_HEADER 1 + +#include +#include + +void EXPORT_FUNC(grub_stop) (void) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_stop_floppy) (void); + +#endif diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h new file mode 100644 index 0000000..fb60668 --- /dev/null +++ b/include/grub/i386/coreboot/kernel.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE +extern char grub_prefix[]; +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/coreboot/loader.h b/include/grub/i386/coreboot/loader.h new file mode 100644 index 0000000..d3f36bb --- /dev/null +++ b/include/grub/i386/coreboot/loader.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/coreboot/machine.h b/include/grub/i386/coreboot/machine.h new file mode 100644 index 0000000..3f278ed --- /dev/null +++ b/include/grub/i386/coreboot/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_LINUXBIOS 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h new file mode 100644 index 0000000..434ae62 --- /dev/null +++ b/include/grub/i386/coreboot/memory.h @@ -0,0 +1,70 @@ +/* memory.h - describe the memory map */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef _GRUB_MEMORY_MACHINE_LB_HEADER +#define _GRUB_MEMORY_MACHINE_LB_HEADER 1 + +#include +#include + +#ifndef ASM_FILE +#include +#include +#endif + +#define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ + +#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ +#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START + +#ifndef ASM_FILE + +struct grub_linuxbios_table_header +{ + char signature[4]; + grub_uint32_t size; +}; +typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; + +struct grub_linuxbios_table_item +{ +#define GRUB_LINUXBIOS_MEMBER_UNUSED 0 +#define GRUB_LINUXBIOS_MEMBER_MEMORY 1 + grub_uint32_t tag; + grub_uint32_t size; +}; +typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t; + +struct grub_linuxbios_mem_region +{ + grub_uint64_t addr; + grub_uint64_t size; +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + grub_uint32_t type; +}; +typedef struct grub_linuxbios_mem_region *mem_region_t; + +void grub_machine_mmap_init (void); + +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); + +#endif + +#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/i386/coreboot/serial.h b/include/grub/i386/coreboot/serial.h new file mode 100644 index 0000000..2c527f6 --- /dev/null +++ b/include/grub/i386/coreboot/serial.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/coreboot/time.h b/include/grub/i386/coreboot/time.h new file mode 100644 index 0000000..2298ee8 --- /dev/null +++ b/include/grub/i386/coreboot/time.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h new file mode 100644 index 0000000..c0549f4 --- /dev/null +++ b/include/grub/i386/efi/kernel.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_KERNEL_HEADER +#define GRUB_MACHINE_KERNEL_HEADER 1 + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_MACHINE_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_MACHINE_DATA_END 0x50 + +#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ + diff --git a/include/grub/i386/efi/loader.h b/include/grub/i386/efi/loader.h new file mode 100644 index 0000000..3308be0 --- /dev/null +++ b/include/grub/i386/efi/loader.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +/* It is necessary to export these functions, because normal mode commands + reuse rescue mode commands. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/efi/machine.h b/include/grub/i386/efi/machine.h new file mode 100644 index 0000000..1600768 --- /dev/null +++ b/include/grub/i386/efi/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_EFI 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/i386/efi/time.h b/include/grub/i386/efi/time.h new file mode 100644 index 0000000..7a9241f --- /dev/null +++ b/include/grub/i386/efi/time.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_TIME_HEADER +#define GRUB_MACHINE_TIME_HEADER 1 + +#include + +#endif /* ! GRUB_MACHINE_TIME_HEADER */ diff --git a/include/grub/i386/halt.h b/include/grub/i386/halt.h new file mode 100644 index 0000000..1c403a7 --- /dev/null +++ b/include/grub/i386/halt.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +extern void grub_halt (void); diff --git a/include/grub/i386/ieee1275/console.h b/include/grub/i386/ieee1275/console.h new file mode 100644 index 0000000..854724a --- /dev/null +++ b/include/grub/i386/ieee1275/console.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CONSOLE_MACHINE_HEADER +#define GRUB_CONSOLE_MACHINE_HEADER 1 + +#include + +/* Initialize the console system. */ +void grub_console_init (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/i386/ieee1275/ieee1275.h b/include/grub/i386/ieee1275/ieee1275.h new file mode 100644 index 0000000..2625f02 --- /dev/null +++ b/include/grub/i386/ieee1275/ieee1275.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h new file mode 100644 index 0000000..dccf8cb --- /dev/null +++ b/include/grub/i386/ieee1275/kernel.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/ieee1275/loader.h b/include/grub/i386/ieee1275/loader.h new file mode 100644 index 0000000..942242b --- /dev/null +++ b/include/grub/i386/ieee1275/loader.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include +#include + +void EXPORT_FUNC(grub_multiboot2_real_boot) (grub_addr_t entry, + struct grub_multiboot_info *mbi) + __attribute__ ((noreturn)); + +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/ieee1275/machine.h b/include/grub/i386/ieee1275/machine.h new file mode 100644 index 0000000..755eb33 --- /dev/null +++ b/include/grub/i386/ieee1275/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_IEEE1275 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/i386/ieee1275/memory.h b/include/grub/i386/ieee1275/memory.h new file mode 100644 index 0000000..386ee4a --- /dev/null +++ b/include/grub/i386/ieee1275/memory.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/ieee1275/serial.h b/include/grub/i386/ieee1275/serial.h new file mode 100644 index 0000000..2c527f6 --- /dev/null +++ b/include/grub/i386/ieee1275/serial.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/ieee1275/time.h b/include/grub/i386/ieee1275/time.h new file mode 100644 index 0000000..6f474ba --- /dev/null +++ b/include/grub/i386/ieee1275/time.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h new file mode 100644 index 0000000..0e56776 --- /dev/null +++ b/include/grub/i386/io.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1996,2000,2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* Based on sys/io.h from GNU libc. */ + +#ifndef GRUB_IO_H +#define GRUB_IO_H 1 + +static __inline unsigned char +grub_inb (unsigned short int port) +{ + unsigned char _v; + + __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned short int +grub_inw (unsigned short int port) +{ + unsigned short _v; + + __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline unsigned int +grub_inl (unsigned short int port) +{ + unsigned int _v; + + __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port)); + return _v; +} + +static __inline void +grub_outb (unsigned char value, unsigned short int port) +{ + __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port)); +} + +static __inline void +grub_outw (unsigned short int value, unsigned short int port) +{ + __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port)); + +} + +static __inline void +grub_outl (unsigned int value, unsigned short int port) +{ + __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port)); +} + +#endif /* _SYS_IO_H */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h new file mode 100644 index 0000000..0dfab05 --- /dev/null +++ b/include/grub/i386/kernel.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#define GRUB_MOD_ALIGN 0x1000 + +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_MOD_GAP 0x0 + +#define GRUB_KERNEL_CPU_PREFIX 0x2 +#define GRUB_KERNEL_CPU_DATA_END 0x42 + +#endif diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h new file mode 100644 index 0000000..d5b5207 --- /dev/null +++ b/include/grub/i386/linux.h @@ -0,0 +1,277 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LINUX_MACHINE_HEADER +#define GRUB_LINUX_MACHINE_HEADER 1 + +#define GRUB_LINUX_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */ +#define GRUB_LINUX_DEFAULT_SETUP_SECTS 4 +#define GRUB_LINUX_FLAG_CAN_USE_HEAP 0x80 +#define GRUB_LINUX_INITRD_MAX_ADDRESS 0x37FFFFFF +#define GRUB_LINUX_MAX_SETUP_SECTS 64 +#define GRUB_LINUX_BOOT_LOADER_TYPE 0x72 +#define GRUB_LINUX_HEAP_END_OFFSET (0x9000 - 0x200) + +#define GRUB_LINUX_BZIMAGE_ADDR 0x100000 +#define GRUB_LINUX_ZIMAGE_ADDR 0x10000 +#define GRUB_LINUX_OLD_REAL_MODE_ADDR 0x90000 +#define GRUB_LINUX_SETUP_STACK 0x9000 + +#define GRUB_LINUX_FLAG_BIG_KERNEL 0x1 + +/* Linux's video mode selection support. Actually I hate it! */ +#define GRUB_LINUX_VID_MODE_NORMAL 0xFFFF +#define GRUB_LINUX_VID_MODE_EXTENDED 0xFFFE +#define GRUB_LINUX_VID_MODE_ASK 0xFFFD + +#define GRUB_LINUX_SETUP_MOVE_SIZE 0x9100 +#define GRUB_LINUX_CL_MAGIC 0xA33F + +#ifdef __x86_64__ + +#define GRUB_LINUX_EFI_SIGNATURE \ + ('4' << 24 | '6' << 16 | 'L' << 8 | 'E') + +#else + +#define GRUB_LINUX_EFI_SIGNATURE \ + ('2' << 24 | '3' << 16 | 'L' << 8 | 'E') + +#endif + +#define GRUB_LINUX_EFI_SIGNATURE_0204 \ + ('L' << 24 | 'I' << 16 | 'F' << 8 | 'E') + +#define GRUB_LINUX_OFW_SIGNATURE \ + (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O') + +#ifndef ASM_FILE + +#define GRUB_E820_RAM 1 +#define GRUB_E820_RESERVED 2 +#define GRUB_E820_ACPI 3 +#define GRUB_E820_NVS 4 +#define GRUB_E820_EXEC_CODE 5 + +#define GRUB_E820_MAX_ENTRY 128 + +struct grub_e820_mmap +{ + grub_uint64_t addr; + grub_uint64_t size; + grub_uint32_t type; +} __attribute__((packed)); + +#define GRUB_VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */ +#define GRUB_VIDEO_TYPE_EFI 0x70 + +/* For the Linux/i386 boot protocol version 2.03. */ +struct linux_kernel_header +{ + grub_uint8_t code1[0x0020]; + grub_uint16_t cl_magic; /* Magic number 0xA33F */ + grub_uint16_t cl_offset; /* The offset of command line */ + grub_uint8_t code2[0x01F1 - 0x0020 - 2 - 2]; + grub_uint8_t setup_sects; /* The size of the setup in sectors */ + grub_uint16_t root_flags; /* If the root is mounted readonly */ + grub_uint16_t syssize; /* obsolete */ + grub_uint16_t swap_dev; /* obsolete */ + grub_uint16_t ram_size; /* obsolete */ + grub_uint16_t vid_mode; /* Video mode control */ + grub_uint16_t root_dev; /* Default root device number */ + grub_uint16_t boot_flag; /* 0xAA55 magic number */ + grub_uint16_t jump; /* Jump instruction */ + grub_uint32_t header; /* Magic signature "HdrS" */ + grub_uint16_t version; /* Boot protocol version supported */ + grub_uint32_t realmode_swtch; /* Boot loader hook */ + grub_uint16_t start_sys; /* The load-low segment (obsolete) */ + grub_uint16_t kernel_version; /* Points to kernel version string */ + grub_uint8_t type_of_loader; /* Boot loader identifier */ +#define LINUX_LOADER_ID_LILO 0x0 +#define LINUX_LOADER_ID_LOADLIN 0x1 +#define LINUX_LOADER_ID_BOOTSECT 0x2 +#define LINUX_LOADER_ID_SYSLINUX 0x3 +#define LINUX_LOADER_ID_ETHERBOOT 0x4 +#define LINUX_LOADER_ID_ELILO 0x5 +#define LINUX_LOADER_ID_GRUB 0x7 +#define LINUX_LOADER_ID_UBOOT 0x8 +#define LINUX_LOADER_ID_XEN 0x9 +#define LINUX_LOADER_ID_GUJIN 0xa +#define LINUX_LOADER_ID_QEMU 0xb + grub_uint8_t loadflags; /* Boot protocol option flags */ + grub_uint16_t setup_move_size; /* Move to high memory size */ + grub_uint32_t code32_start; /* Boot loader hook */ + grub_uint32_t ramdisk_image; /* initrd load address */ + grub_uint32_t ramdisk_size; /* initrd size */ + grub_uint32_t bootsect_kludge; /* obsolete */ + grub_uint16_t heap_end_ptr; /* Free memory after setup end */ + grub_uint16_t pad1; /* Unused */ + char *cmd_line_ptr; /* Points to the kernel command line */ + grub_uint32_t initrd_addr_max; /* Highest address for initrd */ +} __attribute__ ((packed)); + +/* Boot parameters for Linux based on 2.6.12. This is used by the setup + sectors of Linux, and must be simulated by GRUB on EFI, because + the setup sectors depend on BIOS. */ +struct linux_kernel_params +{ + grub_uint8_t video_cursor_x; /* 0 */ + grub_uint8_t video_cursor_y; + + grub_uint16_t ext_mem; /* 2 */ + + grub_uint16_t video_page; /* 4 */ + grub_uint8_t video_mode; /* 6 */ + grub_uint8_t video_width; /* 7 */ + + grub_uint8_t padding1[0xa - 0x8]; + + grub_uint16_t video_ega_bx; /* a */ + + grub_uint8_t padding2[0xe - 0xc]; + + grub_uint8_t video_height; /* e */ + grub_uint8_t have_vga; /* f */ + grub_uint16_t font_size; /* 10 */ + + grub_uint16_t lfb_width; /* 12 */ + grub_uint16_t lfb_height; /* 14 */ + grub_uint16_t lfb_depth; /* 16 */ + grub_uint32_t lfb_base; /* 18 */ + grub_uint32_t lfb_size; /* 1c */ + + grub_uint16_t cl_magic; /* 20 */ + grub_uint16_t cl_offset; + + grub_uint16_t lfb_line_len; /* 24 */ + grub_uint8_t red_mask_size; /* 26 */ + grub_uint8_t red_field_pos; + grub_uint8_t green_mask_size; + grub_uint8_t green_field_pos; + grub_uint8_t blue_mask_size; + grub_uint8_t blue_field_pos; + grub_uint8_t reserved_mask_size; + grub_uint8_t reserved_field_pos; + grub_uint16_t vesapm_segment; /* 2e */ + grub_uint16_t vesapm_offset; /* 30 */ + grub_uint16_t lfb_pages; /* 32 */ + grub_uint16_t vesa_attrib; /* 34 */ + + grub_uint8_t padding3[0x40 - 0x36]; + + grub_uint16_t apm_version; /* 40 */ + grub_uint16_t apm_code_segment; /* 42 */ + grub_uint32_t apm_entry; /* 44 */ + grub_uint16_t apm_16bit_code_segment; /* 48 */ + grub_uint16_t apm_data_segment; /* 4a */ + grub_uint16_t apm_flags; /* 4c */ + grub_uint32_t apm_code_len; /* 4e */ + grub_uint16_t apm_data_len; /* 52 */ + + grub_uint8_t padding4[0x60 - 0x54]; + + grub_uint32_t ist_signature; /* 60 */ + grub_uint32_t ist_command; /* 64 */ + grub_uint32_t ist_event; /* 68 */ + grub_uint32_t ist_perf_level; /* 6c */ + + grub_uint8_t padding5[0x80 - 0x70]; + + grub_uint8_t hd0_drive_info[0x10]; /* 80 */ + grub_uint8_t hd1_drive_info[0x10]; /* 90 */ + grub_uint16_t rom_config_len; /* a0 */ + + grub_uint8_t padding6[0xb0 - 0xa2]; + + grub_uint32_t ofw_signature; /* b0 */ + grub_uint32_t ofw_num_items; /* b4 */ + grub_uint32_t ofw_cif_handler; /* b8 */ + grub_uint32_t ofw_idt; /* bc */ + + grub_uint8_t padding7[0x1b8 - 0xc0]; + + union + { + struct + { + grub_uint32_t efi_system_table; /* 1b8 */ + grub_uint32_t padding7_1; /* 1bc */ + grub_uint32_t efi_signature; /* 1c0 */ + grub_uint32_t efi_mem_desc_size; /* 1c4 */ + grub_uint32_t efi_mem_desc_version; /* 1c8 */ + grub_uint32_t efi_mmap_size; /* 1cc */ + grub_uint32_t efi_mmap; /* 1d0 */ + } v0204; + struct + { + grub_uint32_t padding7_1; /* 1b8 */ + grub_uint32_t padding7_2; /* 1bc */ + grub_uint32_t efi_signature; /* 1c0 */ + grub_uint32_t efi_system_table; /* 1c4 */ + grub_uint32_t efi_mem_desc_size; /* 1c8 */ + grub_uint32_t efi_mem_desc_version; /* 1cc */ + grub_uint32_t efi_mmap; /* 1d0 */ + grub_uint32_t efi_mmap_size; /* 1d4 */ + grub_uint32_t efi_system_table_hi; /* 1d8 */ + grub_uint32_t efi_mmap_hi; /* 1dc */ + } v0206; + }; + + grub_uint32_t alt_mem; /* 1e0 */ + + grub_uint8_t padding8[0x1e8 - 0x1e4]; + + grub_uint32_t mmap_size; /* 1e8 */ + + grub_uint8_t padding9[0x1f1 - 0x1ec]; + + grub_uint8_t setup_sects; /* The size of the setup in sectors */ + grub_uint16_t root_flags; /* If the root is mounted readonly */ + grub_uint16_t syssize; /* obsolete */ + grub_uint16_t swap_dev; /* obsolete */ + grub_uint16_t ram_size; /* obsolete */ + grub_uint16_t vid_mode; /* Video mode control */ + grub_uint16_t root_dev; /* Default root device number */ + + grub_uint8_t padding10; /* 1fe */ + grub_uint8_t ps_mouse; /* 1ff */ + + grub_uint16_t jump; /* Jump instruction */ + grub_uint32_t header; /* Magic signature "HdrS" */ + grub_uint16_t version; /* Boot protocol version supported */ + grub_uint32_t realmode_swtch; /* Boot loader hook */ + grub_uint16_t start_sys; /* The load-low segment (obsolete) */ + grub_uint16_t kernel_version; /* Points to kernel version string */ + grub_uint8_t type_of_loader; /* Boot loader identifier */ + grub_uint8_t loadflags; /* Boot protocol option flags */ + grub_uint16_t setup_move_size; /* Move to high memory size */ + grub_uint32_t code32_start; /* Boot loader hook */ + grub_uint32_t ramdisk_image; /* initrd load address */ + grub_uint32_t ramdisk_size; /* initrd size */ + grub_uint32_t bootsect_kludge; /* obsolete */ + grub_uint16_t heap_end_ptr; /* Free memory after setup end */ + grub_uint16_t pad1; /* Unused */ + grub_uint32_t cmd_line_ptr; /* Points to the kernel command line */ + + grub_uint8_t pad2[164]; /* 22c */ + struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY]; /* 2d0 */ + +} __attribute__ ((packed)); +#endif /* ! ASM_FILE */ + +#endif /* ! GRUB_LINUX_MACHINE_HEADER */ diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h new file mode 100644 index 0000000..9673e82 --- /dev/null +++ b/include/grub/i386/loader.h @@ -0,0 +1,63 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_CPU_HEADER +#define GRUB_LOADER_CPU_HEADER 1 + +#include +#include +#include +#include + +extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size); +extern char *EXPORT_VAR(grub_linux_tmp_addr); +extern char *EXPORT_VAR(grub_linux_real_addr); +extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage); +extern grub_addr_t EXPORT_VAR(grub_os_area_addr); +extern grub_size_t EXPORT_VAR(grub_os_area_size); + +grub_err_t EXPORT_FUNC(grub_linux_boot) (void); + +/* The asm part of the multiboot loader. */ +void EXPORT_FUNC(grub_multiboot_real_boot) (grub_addr_t entry, + struct grub_multiboot_info *mbi) + __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_multiboot2_real_boot) (grub_addr_t entry, + struct grub_multiboot_info *mbi) + __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_unix_real_boot) (grub_addr_t entry, ...) + __attribute__ ((cdecl,noreturn)); + +extern grub_addr_t EXPORT_VAR(grub_multiboot_payload_orig); +extern grub_addr_t EXPORT_VAR(grub_multiboot_payload_dest); +extern grub_size_t EXPORT_VAR(grub_multiboot_payload_size); +extern grub_uint32_t EXPORT_VAR(grub_multiboot_payload_entry_offset); + +/* It is necessary to export these functions, because normal mode commands + reuse rescue mode commands. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +extern grub_uint8_t EXPORT_VAR(grub_multiboot_forward_relocator); +extern grub_uint8_t EXPORT_VAR(grub_multiboot_forward_relocator_end); +extern grub_uint8_t EXPORT_VAR(grub_multiboot_backward_relocator); +extern grub_uint8_t EXPORT_VAR(grub_multiboot_backward_relocator_end); + +#define RELOCATOR_SIZEOF(x) (&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator) + +#endif /* ! GRUB_LOADER_CPU_HEADER */ diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h new file mode 100644 index 0000000..64d4f21 --- /dev/null +++ b/include/grub/i386/pc/biosdisk.h @@ -0,0 +1,126 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BIOSDISK_MACHINE_HEADER +#define GRUB_BIOSDISK_MACHINE_HEADER 1 + +#include +#include + +#define GRUB_BIOSDISK_FLAG_LBA 1 +#define GRUB_BIOSDISK_FLAG_CDROM 2 + +#define GRUB_BIOSDISK_CDTYPE_NO_EMUL 0 +#define GRUB_BIOSDISK_CDTYPE_1_2_M 1 +#define GRUB_BIOSDISK_CDTYPE_1_44_M 2 +#define GRUB_BIOSDISK_CDTYPE_2_88_M 3 +#define GRUB_BIOSDISK_CDTYPE_HARDDISK 4 + +#define GRUB_BIOSDISK_CDTYPE_MASK 0xF + +struct grub_biosdisk_data +{ + int drive; + unsigned long cylinders; + unsigned long heads; + unsigned long sectors; + unsigned long flags; +}; + +/* Drive Parameters. */ +struct grub_biosdisk_drp +{ + grub_uint16_t size; + grub_uint16_t flags; + grub_uint32_t cylinders; + grub_uint32_t heads; + grub_uint32_t sectors; + grub_uint64_t total_sectors; + grub_uint16_t bytes_per_sector; + /* ver 2.0 or higher */ + + union + { + grub_uint32_t EDD_configuration_parameters; + + /* Pointer to the Device Parameter Table Extension (ver 3.0+). */ + grub_uint32_t dpte_pointer; + }; + + /* ver 3.0 or higher */ + grub_uint16_t signature_dpi; + grub_uint8_t length_dpi; + grub_uint8_t reserved[3]; + grub_uint8_t name_of_host_bus[4]; + grub_uint8_t name_of_interface_type[8]; + grub_uint8_t interface_path[8]; + grub_uint8_t device_path[8]; + grub_uint8_t reserved2; + grub_uint8_t checksum; + + /* XXX: This is necessary, because the BIOS of Thinkpad X20 + writes a garbage to the tail of drive parameters, + regardless of a size specified in a caller. */ + grub_uint8_t dummy[16]; +} __attribute__ ((packed)); + +struct grub_biosdisk_cdrp +{ + grub_uint8_t size; + grub_uint8_t media_type; + grub_uint8_t drive_no; + grub_uint8_t controller_no; + grub_uint32_t image_lba; + grub_uint16_t device_spec; + grub_uint16_t cache_seg; + grub_uint16_t load_seg; + grub_uint16_t length_sec512; + grub_uint8_t cylinders; + grub_uint8_t sectors; + grub_uint8_t heads; + grub_uint8_t dummy[16]; +} __attribute__ ((packed)); + +/* Disk Address Packet. */ +struct grub_biosdisk_dap +{ + grub_uint8_t length; + grub_uint8_t reserved; + grub_uint16_t blocks; + grub_uint32_t buffer; + grub_uint64_t block; +} __attribute__ ((packed)); + +int EXPORT_FUNC(grub_biosdisk_rw_int13_extensions) (int ah, int drive, void *dap); +int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hoff, + int soff, int nsec, int segment); +int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive); +int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive, + void *drp); +int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive, + void *cdrp); +int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive, + unsigned long *cylinders, + unsigned long *heads, + unsigned long *sectors); +int EXPORT_FUNC(grub_biosdisk_get_num_floppies) (void); + +void grub_biosdisk_init (void); +void grub_biosdisk_fini (void); + +#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h new file mode 100644 index 0000000..3862214 --- /dev/null +++ b/include/grub/i386/pc/boot.h @@ -0,0 +1,81 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BOOT_MACHINE_HEADER +#define GRUB_BOOT_MACHINE_HEADER 1 + +/* The signature for bootloader. */ +#define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 + +/* The offset of the start of BPB (BIOS Parameter Block). */ +#define GRUB_BOOT_MACHINE_BPB_START 0x3 + +/* The offset of the end of BPB (BIOS Parameter Block). */ +#define GRUB_BOOT_MACHINE_BPB_END 0x3e + +/* The offset of the major version. */ +#define GRUB_BOOT_MACHINE_VER_MAJ 0x3e + +/* The offset of BOOT_DRIVE. */ +#define GRUB_BOOT_MACHINE_BOOT_DRIVE 0x4c + +/* The offset of ROOT_DRIVE. */ +#define GRUB_BOOT_MACHINE_ROOT_DRIVE 0x4d + +/* The offset of KERNEL_ADDRESS. */ +#define GRUB_BOOT_MACHINE_KERNEL_ADDRESS 0x40 + +/* The offset of KERNEL_SECTOR. */ +#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x44 + +/* The offset of KERNEL_SEGMENT. */ +#define GRUB_BOOT_MACHINE_KERNEL_SEGMENT 0x42 + +/* The offset of BOOT_DRIVE_CHECK. */ +#define GRUB_BOOT_MACHINE_DRIVE_CHECK 0x4f + +/* The offset of a magic number used by Windows NT. */ +#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC 0x1b8 + +/* The offset of the start of the partition table. */ +#define GRUB_BOOT_MACHINE_PART_START 0x1be + +/* The offset of the end of the partition table. */ +#define GRUB_BOOT_MACHINE_PART_END 0x1fe + +/* The stack segment. */ +#define GRUB_BOOT_MACHINE_STACK_SEG 0x2000 + +/* The segment of disk buffer. The disk buffer MUST be 32K long and + cannot straddle a 64K boundary. */ +#define GRUB_BOOT_MACHINE_BUFFER_SEG 0x7000 + +/* The flag for BIOS drive number to designate a hard disk vs. a + floppy. */ +#define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80 + +/* The segment where the kernel is loaded. */ +#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800 + +/* The address where the kernel is loaded. */ +#define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4) + +/* The size of a block list used in the kernel startup code. */ +#define GRUB_BOOT_MACHINE_LIST_SIZE 12 + +#endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/chainloader.h b/include/grub/i386/pc/chainloader.h new file mode 100644 index 0000000..c28a42d --- /dev/null +++ b/include/grub/i386/pc/chainloader.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CHAINLOADER_MACHINE_HEADER +#define GRUB_CHAINLOADER_MACHINE_HEADER 1 + +#include + +/* Common function for normal and rescue mode commands. */ +typedef enum + { + GRUB_CHAINLOADER_FORCE = 0x1 + } grub_chainloader_flags_t; + +void EXPORT_FUNC(grub_chainloader_cmd) (const char * file, + grub_chainloader_flags_t flags); + +#endif /* GRUB_CHAINLOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h new file mode 100644 index 0000000..2a74d15 --- /dev/null +++ b/include/grub/i386/pc/console.h @@ -0,0 +1,58 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CONSOLE_MACHINE_HEADER +#define GRUB_CONSOLE_MACHINE_HEADER 1 + +/* Define scan codes. */ +#define GRUB_CONSOLE_KEY_LEFT 0x4B00 +#define GRUB_CONSOLE_KEY_RIGHT 0x4D00 +#define GRUB_CONSOLE_KEY_UP 0x4800 +#define GRUB_CONSOLE_KEY_DOWN 0x5000 +#define GRUB_CONSOLE_KEY_IC 0x5200 +#define GRUB_CONSOLE_KEY_DC 0x5300 +#define GRUB_CONSOLE_KEY_BACKSPACE 0x0008 +#define GRUB_CONSOLE_KEY_HOME 0x4700 +#define GRUB_CONSOLE_KEY_END 0x4F00 +#define GRUB_CONSOLE_KEY_NPAGE 0x5100 +#define GRUB_CONSOLE_KEY_PPAGE 0x4900 + +#ifndef ASM_FILE + +#include +#include +#include +#include + +/* These are global to share code between C and asm. */ +int grub_console_checkkey (void); +int grub_console_getkey (void); +grub_uint16_t grub_console_getxy (void); +void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y); +void grub_console_cls (void); +void grub_console_setcursor (int on); + +/* Initialize the console system. */ +void grub_console_init (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif + +#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h new file mode 100644 index 0000000..f18a0da --- /dev/null +++ b/include/grub/i386/pc/init.h @@ -0,0 +1,50 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_INIT_MACHINE_HEADER +#define GRUB_INIT_MACHINE_HEADER 1 + +#include +#include +#include + +/* Get the memory size in KB. If EXTENDED is zero, return conventional + memory, otherwise return extended memory. */ +grub_uint16_t grub_get_memsize (int extended); + +/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB + in 1KB parts, and upper 16 bits are above 16MB in 64KB parts. */ +grub_uint32_t grub_get_eisa_mmap (void); + +/* Get a memory map entry. Return next continuation value. Zero means + the end. */ +grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry, + grub_uint32_t cont); + +/* Turn on/off Gate A20. */ +void grub_gate_a20 (int on); + +/* Reboot the machine. */ +void EXPORT_FUNC (grub_reboot) (void); + +/* Halt the system, using APM if possible. If NO_APM is true, don't + * use APM even if it is available. */ +void EXPORT_FUNC (grub_halt) (int no_apm); + + +#endif /* ! GRUB_INIT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h new file mode 100644 index 0000000..b6650bc --- /dev/null +++ b/include/grub/i386/pc/kernel.h @@ -0,0 +1,82 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_HEADER +#define KERNEL_MACHINE_HEADER 1 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_INSTALL_DOS_PART. */ +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART 0x14 + +/* The offset of GRUB_INSTALL_BSD_PART. */ +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART 0x18 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_MACHINE_PREFIX 0x1c + +/* End of the data section. */ +#define GRUB_KERNEL_MACHINE_DATA_END 0x5c + +/* The size of the first region which won't be compressed. */ +#if defined(ENABLE_LZO) +#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x450) +#elif defined(ENABLE_LZMA) +#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#endif + +#ifndef ASM_FILE + +#include +#include + +/* The size of kernel image. */ +extern grub_int32_t grub_kernel_image_size; + +/* The total size of module images following the kernel. */ +extern grub_int32_t grub_total_module_size; + +/* The DOS partition number of the installed partition. */ +extern grub_int32_t grub_install_dos_part; + +/* The BSD partition number of the installed partition. */ +extern grub_int32_t grub_install_bsd_part; + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +/* The boot BIOS drive number. */ +extern grub_int32_t EXPORT_VAR(grub_boot_drive); + +/* The root BIOS drive number. */ +extern grub_int32_t grub_root_drive; + +/* The end address of the kernel. */ +extern grub_addr_t grub_end_addr; + +#endif /* ! ASM_FILE */ + +#endif /* ! KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/loader.h b/include/grub/i386/pc/loader.h new file mode 100644 index 0000000..3e03141 --- /dev/null +++ b/include/grub/i386/pc/loader.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include + +/* This is an asm part of the chainloader. */ +void EXPORT_FUNC(grub_chainloader_real_boot) (int drive, void *part_addr) __attribute__ ((noreturn)); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/machine.h b/include/grub/i386/pc/machine.h new file mode 100644 index 0000000..e6de728 --- /dev/null +++ b/include/grub/i386/pc/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_PCBIOS 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h new file mode 100644 index 0000000..08e92a9 --- /dev/null +++ b/include/grub/i386/pc/memory.h @@ -0,0 +1,103 @@ +/* memory.h - describe the memory map */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#include +#include +#ifndef ASM_FILE +#include +#include +#endif + +/* The scratch buffer used in real mode code. */ +#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 +#define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) +#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE 0x10000 + +/* The real mode stack. */ +#define GRUB_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10) + +/* The size of the protect mode stack. */ +#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 + +/* The upper memory area (starting at 640 kiB). */ +#define GRUB_MEMORY_MACHINE_UPPER 0xa0000 + +/* The protected mode stack. */ +#define GRUB_MEMORY_MACHINE_PROT_STACK \ + (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ + + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10) + +/* The memory area where GRUB uses its own purpose. This part is not added + into free memory for dynamic allocations. */ +#define GRUB_MEMORY_MACHINE_RESERVED_START \ + GRUB_MEMORY_MACHINE_SCRATCH_ADDR +#define GRUB_MEMORY_MACHINE_RESERVED_END \ + (GRUB_MEMORY_MACHINE_PROT_STACK + 0x10) + +/* The area where GRUB is decompressed at early startup. */ +#define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR 0x100000 + +/* The address of a partition table passed to another boot loader. */ +#define GRUB_MEMORY_MACHINE_PART_TABLE_ADDR 0x7be + +/* The address where another boot loader is loaded. */ +#define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 + +/* The flag for protected mode. */ +#define GRUB_MEMORY_MACHINE_CR0_PE_ON 0x1 + +/* The code segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 + +/* The data segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 + +/* The code segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 + +/* The data segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 + +#ifndef ASM_FILE + +#ifndef GRUB_MACHINE_IEEE1275 +extern grub_size_t EXPORT_VAR(grub_lower_mem); +#endif + +extern grub_size_t EXPORT_VAR(grub_upper_mem); + +struct grub_machine_mmap_entry +{ + grub_uint32_t size; + grub_uint64_t addr; + grub_uint64_t len; +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_RESERVED 2 + grub_uint32_t type; +} __attribute__((packed)); + +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); + +#endif + +#endif /* ! GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/pxe.h b/include/grub/i386/pc/pxe.h new file mode 100644 index 0000000..4821328 --- /dev/null +++ b/include/grub/i386/pc/pxe.h @@ -0,0 +1,318 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_PXE_H +#define GRUB_CPU_PXE_H + +#include + +#define GRUB_PXENV_TFTP_OPEN 0x0020 +#define GRUB_PXENV_TFTP_CLOSE 0x0021 +#define GRUB_PXENV_TFTP_READ 0x0022 +#define GRUB_PXENV_TFTP_READ_FILE 0x0023 +#define GRUB_PXENV_TFTP_READ_FILE_PMODE 0x0024 +#define GRUB_PXENV_TFTP_GET_FSIZE 0x0025 + +#define GRUB_PXENV_UDP_OPEN 0x0030 +#define GRUB_PXENV_UDP_CLOSE 0x0031 +#define GRUB_PXENV_UDP_READ 0x0032 +#define GRUB_PXENV_UDP_WRITE 0x0033 + +#define GRUB_PXENV_START_UNDI 0x0000 +#define GRUB_PXENV_UNDI_STARTUP 0x0001 +#define GRUB_PXENV_UNDI_CLEANUP 0x0002 +#define GRUB_PXENV_UNDI_INITIALIZE 0x0003 +#define GRUB_PXENV_UNDI_RESET_NIC 0x0004 +#define GRUB_PXENV_UNDI_SHUTDOWN 0x0005 +#define GRUB_PXENV_UNDI_OPEN 0x0006 +#define GRUB_PXENV_UNDI_CLOSE 0x0007 +#define GRUB_PXENV_UNDI_TRANSMIT 0x0008 +#define GRUB_PXENV_UNDI_SET_MCAST_ADDR 0x0009 +#define GRUB_PXENV_UNDI_SET_STATION_ADDR 0x000A +#define GRUB_PXENV_UNDI_SET_PACKET_FILTER 0x000B +#define GRUB_PXENV_UNDI_GET_INFORMATION 0x000C +#define GRUB_PXENV_UNDI_GET_STATISTICS 0x000D +#define GRUB_PXENV_UNDI_CLEAR_STATISTICS 0x000E +#define GRUB_PXENV_UNDI_INITIATE_DIAGS 0x000F +#define GRUB_PXENV_UNDI_FORCE_INTERRUPT 0x0010 +#define GRUB_PXENV_UNDI_GET_MCAST_ADDR 0x0011 +#define GRUB_PXENV_UNDI_GET_NIC_TYPE 0x0012 +#define GRUB_PXENV_UNDI_GET_IFACE_INFO 0x0013 +#define GRUB_PXENV_UNDI_ISR 0x0014 +#define GRUB_PXENV_STOP_UNDI 0x0015 +#define GRUB_PXENV_UNDI_GET_STATE 0x0015 + +#define GRUB_PXENV_UNLOAD_STACK 0x0070 +#define GRUB_PXENV_GET_CACHED_INFO 0x0071 +#define GRUB_PXENV_RESTART_DHCP 0x0072 +#define GRUB_PXENV_RESTART_TFTP 0x0073 +#define GRUB_PXENV_MODE_SWITCH 0x0074 +#define GRUB_PXENV_START_BASE 0x0075 +#define GRUB_PXENV_STOP_BASE 0x0076 + +#define GRUB_PXENV_EXIT_SUCCESS 0x0000 +#define GRUB_PXENV_EXIT_FAILURE 0x0001 + +#define GRUB_PXENV_STATUS_SUCCESS 0x00 +#define GRUB_PXENV_STATUS_FAILURE 0x01 +#define GRUB_PXENV_STATUS_BAD_FUNC 0x02 +#define GRUB_PXENV_STATUS_UNSUPPORTED 0x03 +#define GRUB_PXENV_STATUS_KEEP_UNDI 0x04 +#define GRUB_PXENV_STATUS_KEEP_ALL 0x05 +#define GRUB_PXENV_STATUS_OUT_OF_RESOURCES 0x06 +#define GRUB_PXENV_STATUS_ARP_TIMEOUT 0x11 +#define GRUB_PXENV_STATUS_UDP_CLOSED 0x18 +#define GRUB_PXENV_STATUS_UDP_OPEN 0x19 +#define GRUB_PXENV_STATUS_TFTP_CLOSED 0x1A +#define GRUB_PXENV_STATUS_TFTP_OPEN 0x1B +#define GRUB_PXENV_STATUS_MCOPY_PROBLEM 0x20 +#define GRUB_PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x21 +#define GRUB_PXENV_STATUS_BIS_VALIDATE_FAILURE 0x22 +#define GRUB_PXENV_STATUS_BIS_INIT_FAILURE 0x23 +#define GRUB_PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x24 +#define GRUB_PXENV_STATUS_BIS_GBOA_FAILURE 0x25 +#define GRUB_PXENV_STATUS_BIS_FREE_FAILURE 0x26 +#define GRUB_PXENV_STATUS_BIS_GSI_FAILURE 0x27 +#define GRUB_PXENV_STATUS_BIS_BAD_CKSUM 0x28 +#define GRUB_PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x30 +#define GRUB_PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x32 + +#define GRUB_PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x33 +#define GRUB_PXENV_STATUS_TFTP_READ_TIMEOUT 0x35 +#define GRUB_PXENV_STATUS_TFTP_ERROR_OPCODE 0x36 +#define GRUB_PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x38 +#define GRUB_PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x39 +#define GRUB_PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x3A +#define GRUB_PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x3B +#define GRUB_PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x3C +#define GRUB_PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x3D +#define GRUB_PXENV_STATUS_TFTP_NO_FILESIZE 0x3E +#define GRUB_PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x3F +#define GRUB_PXENV_STATUS_DHCP_TIMEOUT 0x51 +#define GRUB_PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x52 +#define GRUB_PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x53 +#define GRUB_PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x54 +#define GRUB_PXENV_STATUS_UNDI_INVALID_FUNCTION 0x60 +#define GRUB_PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x61 +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x62 +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x63 +#define GRUB_PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x64 +#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x65 +#define GRUB_PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x66 +#define GRUB_PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x67 +#define GRUB_PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x68 +#define GRUB_PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x69 +#define GRUB_PXENV_STATUS_UNDI_INVALID_STATE 0x6A +#define GRUB_PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x6B +#define GRUB_PXENV_STATUS_UNDI_INVALID_PARAMETER 0x6C +#define GRUB_PXENV_STATUS_BSTRAP_PROMPT_MENU 0x74 +#define GRUB_PXENV_STATUS_BSTRAP_MCAST_ADDR 0x76 +#define GRUB_PXENV_STATUS_BSTRAP_MISSING_LIST 0x77 +#define GRUB_PXENV_STATUS_BSTRAP_NO_RESPONSE 0x78 +#define GRUB_PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x79 +#define GRUB_PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0xA0 +#define GRUB_PXENV_STATUS_BINL_NO_PXE_SERVER 0xA1 +#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0xA2 +#define GRUB_PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0xA3 +#define GRUB_PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0xB0 +#define GRUB_PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0xC0 +#define GRUB_PXENV_STATUS_LOADER_NO_BC_ROMID 0xC1 +#define GRUB_PXENV_STATUS_LOADER_BAD_BC_ROMID 0xC2 +#define GRUB_PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0xC3 +#define GRUB_PXENV_STATUS_LOADER_NO_UNDI_ROMID 0xC4 +#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0xC5 +#define GRUB_PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0xC6 +#define GRUB_PXENV_STATUS_LOADER_NO_PXE_STRUCT 0xC8 +#define GRUB_PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0xC9 +#define GRUB_PXENV_STATUS_LOADER_UNDI_START 0xCA +#define GRUB_PXENV_STATUS_LOADER_BC_START 0xCB + +#define GRUB_PXENV_PACKET_TYPE_DHCP_DISCOVER 1 +#define GRUB_PXENV_PACKET_TYPE_DHCP_ACK 2 +#define GRUB_PXENV_PACKET_TYPE_CACHED_REPLY 3 + +#define GRUB_PXE_BOOTP_REQ 1 +#define GRUB_PXE_BOOTP_REP 2 + +#define GRUB_PXE_BOOTP_BCAST 0x8000 + +#if 1 +#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size. */ +#else +#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size. */ +#endif + +#define GRUB_PXE_MIN_BLKSIZE 512 +#define GRUB_PXE_MAX_BLKSIZE 1432 + +#define GRUB_PXE_TFTP_PORT 69 + +#define GRUB_PXE_VM_RFC1048 0x63825363L + +#define GRUB_PXE_ERR_LEN 0xFFFFFFFF + +#ifndef ASM_FILE + +struct grub_pxenv +{ + grub_uint8_t signature[6]; /* 'PXENV+'. */ + grub_uint16_t version; /* MSB = major, LSB = minor. */ + grub_uint8_t length; /* structure length. */ + grub_uint8_t checksum; /* checksum pad. */ + grub_uint32_t rm_entry; /* SEG:OFF to PXE entry point. */ + grub_uint32_t pm_offset; /* Protected mode entry. */ + grub_uint16_t pm_selector; /* Protected mode selector. */ + grub_uint16_t stack_seg; /* Stack segment address. */ + grub_uint16_t stack_size; /* Stack segment size (bytes). */ + grub_uint16_t bc_code_seg; /* BC Code segment address. */ + grub_uint16_t bc_code_size; /* BC Code segment size (bytes). */ + grub_uint16_t bc_data_seg; /* BC Data segment address. */ + grub_uint16_t bc_data_size; /* BC Data segment size (bytes). */ + grub_uint16_t undi_data_seg; /* UNDI Data segment address. */ + grub_uint16_t undi_data_size; /* UNDI Data segment size (bytes). */ + grub_uint16_t undi_code_seg; /* UNDI Code segment address. */ + grub_uint16_t undi_code_size; /* UNDI Code segment size (bytes). */ + grub_uint32_t pxe_ptr; /* SEG:OFF to !PXE struct. */ +} __attribute__ ((packed)); + +struct grub_pxenv_get_cached_info +{ + grub_uint16_t status; + grub_uint16_t packet_type; + grub_uint16_t buffer_size; + grub_uint32_t buffer; + grub_uint16_t buffer_limit; +} __attribute__ ((packed)); + +#define GRUB_PXE_MAC_ADDR_LEN 16 + +typedef grub_uint8_t grub_pxe_mac_addr[GRUB_PXE_MAC_ADDR_LEN]; + +struct grub_pxenv_boot_player +{ + grub_uint8_t opcode; + grub_uint8_t hw_type; /* hardware type. */ + grub_uint8_t hw_len; /* hardware addr len. */ + grub_uint8_t gate_hops; /* zero it. */ + grub_uint32_t ident; /* random number chosen by client. */ + grub_uint16_t seconds; /* seconds since did initial bootstrap. */ + grub_uint16_t flags; + grub_uint32_t client_ip; + grub_uint32_t your_ip; + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; + grub_pxe_mac_addr mac_addr; + grub_uint8_t server_name[64]; + grub_uint8_t boot_file[128]; + union + { + grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options. */ + struct + { + grub_uint32_t magic; /* DHCP magic cookie. */ + grub_uint32_t flags; /* bootp flags/opcodes. */ + grub_uint8_t padding[56]; + } v; + } vendor; +} __attribute__ ((packed)); + +struct grub_pxenv_tftp_open +{ + grub_uint16_t status; + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; + grub_uint8_t filename[128]; + grub_uint16_t tftp_port; + grub_uint16_t packet_size; +} __attribute__ ((packed)); + +struct grub_pxenv_tftp_close +{ + grub_uint16_t status; +} __attribute__ ((packed)); + +struct grub_pxenv_tftp_read +{ + grub_uint16_t status; + grub_uint16_t packet_number; + grub_uint16_t buffer_size; + grub_uint32_t buffer; +} __attribute__ ((packed)); + +struct grub_pxenv_tftp_get_fsize +{ + grub_uint16_t status; + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; + grub_uint8_t filename[128]; + grub_uint32_t file_size; +} __attribute__ ((packed)); + +struct grub_pxenv_udp_open +{ + grub_uint16_t status; + grub_uint32_t src_ip; +} __attribute__ ((packed)); + +struct grub_pxenv_udp_close +{ + grub_uint16_t status; +} __attribute__ ((packed)); + +struct grub_pxenv_udp_write +{ + grub_uint16_t status; + grub_uint32_t ip; + grub_uint32_t gateway; + grub_uint16_t src_port; + grub_uint16_t dst_port; + grub_uint16_t buffer_size; + grub_uint32_t buffer; +} __attribute__ ((packed)); + +struct grub_pxenv_udp_read +{ + grub_uint16_t status; + grub_uint32_t src_ip; + grub_uint32_t dst_ip; + grub_uint16_t src_port; + grub_uint16_t dst_port; + grub_uint16_t buffer_size; + grub_uint32_t buffer; +} __attribute__ ((packed)); + +struct grub_pxenv_unload_stack +{ + grub_uint16_t status; + grub_uint8_t reserved[10]; +} __attribute__ ((packed)); + +struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void); +int EXPORT_FUNC(grub_pxe_call) (int func, void * data); + +extern struct grub_pxenv *grub_pxe_pxenv; +extern grub_uint32_t grub_pxe_your_ip; +extern grub_uint32_t grub_pxe_server_ip; +extern grub_uint32_t grub_pxe_gateway_ip; +extern int grub_pxe_blksize; + +void grub_pxe_unload (void); + +#endif + +#endif /* GRUB_CPU_PXE_H */ diff --git a/include/grub/i386/pc/serial.h b/include/grub/i386/pc/serial.h new file mode 100644 index 0000000..0632ff7 --- /dev/null +++ b/include/grub/i386/pc/serial.h @@ -0,0 +1,67 @@ +/* serial.h - serial device interface */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SERIAL_MACHINE_HEADER +#define GRUB_SERIAL_MACHINE_HEADER 1 + +/* Macros. */ + +/* The offsets of UART registers. */ +#define UART_TX 0 +#define UART_RX 0 +#define UART_DLL 0 +#define UART_IER 1 +#define UART_DLH 1 +#define UART_IIR 2 +#define UART_FCR 2 +#define UART_LCR 3 +#define UART_MCR 4 +#define UART_LSR 5 +#define UART_MSR 6 +#define UART_SR 7 + +/* For LSR bits. */ +#define UART_DATA_READY 0x01 +#define UART_EMPTY_TRANSMITTER 0x20 + +/* The type of parity. */ +#define UART_NO_PARITY 0x00 +#define UART_ODD_PARITY 0x08 +#define UART_EVEN_PARITY 0x18 + +/* The type of word length. */ +#define UART_5BITS_WORD 0x00 +#define UART_6BITS_WORD 0x01 +#define UART_7BITS_WORD 0x02 +#define UART_8BITS_WORD 0x03 + +/* The type of the length of stop bit. */ +#define UART_1_STOP_BIT 0x00 +#define UART_2_STOP_BITS 0x04 + +/* the switch of DLAB. */ +#define UART_DLAB 0x80 + +/* Enable the FIFO. */ +#define UART_ENABLE_FIFO 0xC7 + +/* Turn on DTR, RTS, and OUT2. */ +#define UART_ENABLE_MODEM 0x0B + +#endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h new file mode 100644 index 0000000..98399b6 --- /dev/null +++ b/include/grub/i386/pc/time.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 18 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h new file mode 100644 index 0000000..9a8cb95 --- /dev/null +++ b/include/grub/i386/pc/vbe.h @@ -0,0 +1,277 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VBE_MACHINE_HEADER +#define GRUB_VBE_MACHINE_HEADER 1 + +#include +#include +#include +#include + +/* Default video mode to be used. */ +#define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101 + +/* VBE status codes. */ +#define GRUB_VBE_STATUS_OK 0x004f + +/* Bits from the GRUB_VBE "mode_attributes" field in the mode info struct. */ +#define GRUB_VBE_MODEATTR_SUPPORTED (1 << 0) +#define GRUB_VBE_MODEATTR_RESERVED_1 (1 << 1) +#define GRUB_VBE_MODEATTR_BIOS_TTY_OUTPUT_SUPPORT (1 << 2) +#define GRUB_VBE_MODEATTR_COLOR (1 << 3) +#define GRUB_VBE_MODEATTR_GRAPHICS (1 << 4) +#define GRUB_VBE_MODEATTR_VGA_COMPATIBLE (1 << 5) +#define GRUB_VBE_MODEATTR_VGA_WINDOWED_AVAIL (1 << 6) +#define GRUB_VBE_MODEATTR_LFB_AVAIL (1 << 7) +#define GRUB_VBE_MODEATTR_DOUBLE_SCAN_AVAIL (1 << 8) +#define GRUB_VBE_MODEATTR_INTERLACED_AVAIL (1 << 9) +#define GRUB_VBE_MODEATTR_TRIPLE_BUF_AVAIL (1 << 10) +#define GRUB_VBE_MODEATTR_STEREO_AVAIL (1 << 11) +#define GRUB_VBE_MODEATTR_DUAL_DISPLAY_START (1 << 12) + +/* Values for the GRUB_VBE memory_model field in the mode info struct. */ +#define GRUB_VBE_MEMORY_MODEL_TEXT 0x00 +#define GRUB_VBE_MEMORY_MODEL_CGA 0x01 +#define GRUB_VBE_MEMORY_MODEL_HERCULES 0x02 +#define GRUB_VBE_MEMORY_MODEL_PLANAR 0x03 +#define GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL 0x04 +#define GRUB_VBE_MEMORY_MODEL_NONCHAIN4_256 0x05 +#define GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR 0x06 +#define GRUB_VBE_MEMORY_MODEL_YUV 0x07 + +/* Note: + + Please refer to VESA BIOS Extension 3.0 Specification for more descriptive + meanings of following structures and how they should be used. + + I have tried to maintain field name compatibility against specification + while following naming conventions used in GRUB. */ + +typedef grub_uint32_t grub_vbe_farptr_t; +typedef grub_uint32_t grub_vbe_physptr_t; +typedef grub_uint32_t grub_vbe_status_t; + +struct grub_vbe_info_block +{ + grub_uint8_t signature[4]; + grub_uint16_t version; + + grub_vbe_farptr_t oem_string_ptr; + grub_uint32_t capabilities; + grub_vbe_farptr_t video_mode_ptr; + grub_uint16_t total_memory; + + grub_uint16_t oem_software_rev; + grub_vbe_farptr_t oem_vendor_name_ptr; + grub_vbe_farptr_t oem_product_name_ptr; + grub_vbe_farptr_t oem_product_rev_ptr; + + grub_uint8_t reserved[222]; + + grub_uint8_t oem_data[256]; +} __attribute__ ((packed)); + +struct grub_vbe_mode_info_block +{ + /* Mandatory information for all VBE revisions. */ + grub_uint16_t mode_attributes; + grub_uint8_t win_a_attributes; + grub_uint8_t win_b_attributes; + grub_uint16_t win_granularity; + grub_uint16_t win_size; + grub_uint16_t win_a_segment; + grub_uint16_t win_b_segment; + grub_vbe_farptr_t win_func_ptr; + grub_uint16_t bytes_per_scan_line; + + /* Mandatory information for VBE 1.2 and above. */ + grub_uint16_t x_resolution; + grub_uint16_t y_resolution; + grub_uint8_t x_char_size; + grub_uint8_t y_char_size; + grub_uint8_t number_of_planes; + grub_uint8_t bits_per_pixel; + grub_uint8_t number_of_banks; + grub_uint8_t memory_model; + grub_uint8_t bank_size; + grub_uint8_t number_of_image_pages; + grub_uint8_t reserved; + + /* Direct Color fields (required for direct/6 and YUV/7 memory models). */ + grub_uint8_t red_mask_size; + grub_uint8_t red_field_position; + grub_uint8_t green_mask_size; + grub_uint8_t green_field_position; + grub_uint8_t blue_mask_size; + grub_uint8_t blue_field_position; + grub_uint8_t rsvd_mask_size; + grub_uint8_t rsvd_field_position; + grub_uint8_t direct_color_mode_info; + + /* Mandatory information for VBE 2.0 and above. */ + grub_vbe_physptr_t phys_base_addr; + grub_uint32_t reserved2; + grub_uint16_t reserved3; + + /* Mandatory information for VBE 3.0 and above. */ + grub_uint16_t lin_bytes_per_scan_line; + grub_uint8_t bnk_number_of_image_pages; + grub_uint8_t lin_number_of_image_pages; + grub_uint8_t lin_red_mask_size; + grub_uint8_t lin_red_field_position; + grub_uint8_t lin_green_mask_size; + grub_uint8_t lin_green_field_position; + grub_uint8_t lin_blue_mask_size; + grub_uint8_t lin_blue_field_position; + grub_uint8_t lin_rsvd_mask_size; + grub_uint8_t lin_rsvd_field_position; + grub_uint32_t max_pixel_clock; + + /* Reserved field to make structure to be 256 bytes long, VESA BIOS + Extension 3.0 Specification says to reserve 189 bytes here but + that doesn't make structure to be 256 bytes. So additional one is + added here. */ + grub_uint8_t reserved4[189 + 1]; +} __attribute__ ((packed)); + +struct grub_vbe_crtc_info_block +{ + grub_uint16_t horizontal_total; + grub_uint16_t horizontal_sync_start; + grub_uint16_t horizontal_sync_end; + grub_uint16_t vertical_total; + grub_uint16_t vertical_sync_start; + grub_uint16_t vertical_sync_end; + grub_uint8_t flags; + grub_uint32_t pixel_clock; + grub_uint16_t refresh_rate; + grub_uint8_t reserved[40]; +} __attribute__ ((packed)); + +struct grub_vbe_palette_data +{ + grub_uint8_t blue; + grub_uint8_t green; + grub_uint8_t red; + grub_uint8_t alignment; +} __attribute__ ((packed)); + +/* Prototypes for kernel real mode thunks. */ + +/* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vbe_info_block *controller_info); + +/* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode, + struct grub_vbe_mode_info_block *mode_info); + +/* Call VESA BIOS 0x4f02 to set video mode, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode, + struct grub_vbe_crtc_info_block *crtc_info); + +/* Call VESA BIOS 0x4f03 to return current VBE Mode, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode) (grub_uint32_t *mode); + +/* Call VESA BIOS 0x4f05 to set memory window, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_memory_window) (grub_uint32_t window, + grub_uint32_t position); + +/* Call VESA BIOS 0x4f05 to return memory window, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_memory_window) (grub_uint32_t window, + grub_uint32_t *position); + +/* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_scanline_length) (grub_uint32_t length); + +/* Call VESA BIOS 0x4f06 to return scanline length (in bytes), return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_scanline_length) (grub_uint32_t *length); + +/* Call VESA BIOS 0x4f07 to set display start, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_display_start) (grub_uint32_t x, + grub_uint32_t y); + +/* Call VESA BIOS 0x4f07 to get display start, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_display_start) (grub_uint32_t *x, + grub_uint32_t *y); + +/* Call VESA BIOS 0x4f09 to set palette data, return status. */ +grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_palette_data) (grub_uint32_t color_count, + grub_uint32_t start_index, + struct grub_vbe_palette_data *palette_data); + +/* Prototypes for helper functions. */ + +grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block); +grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode, + struct grub_vbe_mode_info_block *mode_info); +grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode); +grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode, + struct grub_vbe_mode_info_block *mode_info); + +/* VBE module internal prototypes (should not be used from elsewhere). */ +struct grub_video_i386_vbeblit_info; + +struct grub_video_render_target +{ + /* Copy of the screen's mode info structure, except that width, height and + mode_type has been re-adjusted to requested render target settings. */ + struct grub_video_mode_info mode_info; + + struct + { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + } viewport; + + /* Indicates whether the data has been allocated by us and must be freed + when render target is destroyed. */ + int is_allocated; + + /* Pointer to data. Can either be in video card memory or in local host's + memory. */ + void *data; +}; + +grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source, + grub_uint32_t x, grub_uint32_t y); + +grub_video_color_t grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue); + +grub_video_color_t grub_video_vbe_map_rgba (grub_uint8_t red, + grub_uint8_t green, + grub_uint8_t blue, + grub_uint8_t alpha); + +grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color, + grub_uint8_t *red, + grub_uint8_t *green, + grub_uint8_t *blue, + grub_uint8_t *alpha); + +void grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info *source, + grub_video_color_t color, + grub_uint8_t *red, + grub_uint8_t *green, + grub_uint8_t *blue, + grub_uint8_t *alpha); + +#endif /* ! GRUB_VBE_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/vbeblit.h b/include/grub/i386/pc/vbeblit.h new file mode 100644 index 0000000..5a2aa7a --- /dev/null +++ b/include/grub/i386/pc/vbeblit.h @@ -0,0 +1,134 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VBEBLIT_MACHINE_HEADER +#define GRUB_VBEBLIT_MACHINE_HEADER 1 + +/* NOTE: This header is private header for vbe driver and should not be used + in other parts of the code. */ + +struct grub_video_i386_vbeblit_info; + +void +grub_video_i386_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_directN (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_BGR888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_index_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_replace_index_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +void +grub_video_i386_vbeblit_blend_index_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y); + +#endif /* ! GRUB_VBEBLIT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/vbefill.h b/include/grub/i386/pc/vbefill.h new file mode 100644 index 0000000..efc6378 --- /dev/null +++ b/include/grub/i386/pc/vbefill.h @@ -0,0 +1,52 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VBEFILL_MACHINE_HEADER +#define GRUB_VBEFILL_MACHINE_HEADER 1 + +/* NOTE: This header is private header for vbe driver and should not be used + in other parts of the code. */ + +struct grub_video_i386_vbeblit_info; + +void +grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height); + +void +grub_video_i386_vbefill_direct32 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height); + +void +grub_video_i386_vbefill_direct24 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height); + +void +grub_video_i386_vbefill_direct16 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height); + +void +grub_video_i386_vbefill_direct8 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height); + +#endif /* ! GRUB_VBEFILL_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/vbeutil.h b/include/grub/i386/pc/vbeutil.h new file mode 100644 index 0000000..9b5be21 --- /dev/null +++ b/include/grub/i386/pc/vbeutil.h @@ -0,0 +1,43 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* NOTE: This header is private header for vbe driver and should not be used + in other parts of the code. */ + +#ifndef GRUB_VBEUTIL_MACHINE_HEADER +#define GRUB_VBEUTIL_MACHINE_HEADER 1 + +#include +#include + +struct grub_video_i386_vbeblit_info +{ + struct grub_video_mode_info *mode_info; + void *data; +}; + +grub_uint8_t *get_data_ptr (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y); + +grub_video_color_t get_pixel (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y); + +void set_pixel (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y, grub_video_color_t color); + +#endif /* ! GRUB_VBEUTIL_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/vga.h b/include/grub/i386/pc/vga.h new file mode 100644 index 0000000..b982239 --- /dev/null +++ b/include/grub/i386/pc/vga.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VGA_MACHINE_HEADER +#define GRUB_VGA_MACHINE_HEADER 1 + +#include +#include + +/* The VGA (at the beginning of upper memory). */ +#define GRUB_MEMORY_MACHINE_VGA_ADDR GRUB_MEMORY_MACHINE_UPPER + +/* Set the video mode to MODE and return the previous mode. */ +unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode); + +/* Return a pointer to the ROM font table. */ +unsigned char *EXPORT_FUNC(grub_vga_get_font) (void); + +#endif /* ! GRUB_VGA_MACHINE_HEADER */ diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h new file mode 100644 index 0000000..f4f08ab --- /dev/null +++ b/include/grub/i386/pci.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_PCI_H +#define GRUB_CPU_PCI_H 1 + +#include +#include + +#define GRUB_PCI_ADDR_REG 0xcf8 +#define GRUB_PCI_DATA_REG 0xcfc + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + grub_outl (addr, GRUB_PCI_ADDR_REG); + return grub_inl (GRUB_PCI_DATA_REG); +} + +#endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h new file mode 100644 index 0000000..0da271d --- /dev/null +++ b/include/grub/i386/pit.h @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_PIT_HEADER +#define KERNEL_CPU_PIT_HEADER 1 + +#include + +extern void grub_pit_wait (grub_uint16_t tics); + +#endif /* ! KERNEL_CPU_PIT_HEADER */ diff --git a/include/grub/i386/reboot.h b/include/grub/i386/reboot.h new file mode 100644 index 0000000..5bcbb5d --- /dev/null +++ b/include/grub/i386/reboot.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +extern void grub_reboot (void); diff --git a/include/grub/i386/setjmp.h b/include/grub/i386/setjmp.h new file mode 100644 index 0000000..02b0d8f --- /dev/null +++ b/include/grub/i386/setjmp.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long grub_jmp_buf[6]; + +int grub_setjmp (grub_jmp_buf env) __attribute__ ((cdecl, regparm (3))); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn, cdecl, + regparm (3))); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/i386/time.h b/include/grub/i386/time.h new file mode 100644 index 0000000..842882c --- /dev/null +++ b/include/grub/i386/time.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: this can't work until we handle interrupts. */ +/* __asm__ __volatile__ ("hlt"); */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h new file mode 100644 index 0000000..9633701 --- /dev/null +++ b/include/grub/i386/tsc.h @@ -0,0 +1,107 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TSC_HEADER +#define KERNEL_CPU_TSC_HEADER 1 + +#include + +/* Read the TSC value, which increments with each CPU clock cycle. */ +static __inline grub_uint64_t +grub_get_tsc (void) +{ + grub_uint32_t lo, hi; + + /* The CPUID instruction is a 'serializing' instruction, and + avoids out-of-order execution of the RDTSC instruction. */ + __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" + "cpuid":::"%rax", "%rbx", "%rcx", "%rdx"); + /* Read TSC value. We cannot use "=A", since this would use + %rax on x86_64. */ + __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); + + return (((grub_uint64_t) hi) << 32) | lo; +} + +#ifdef __x86_64__ + +static __inline int +grub_cpu_is_cpuid_supported (void) +{ + grub_uint64_t id_supported; + + __asm__ ("pushfq\n\t" + "popq %%rax /* Get EFLAGS into EAX */\n\t" + "movq %%rax, %%rcx /* Save original flags in ECX */\n\t" + "xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t" + "pushq %%rax /* Store modified EFLAGS on stack */\n\t" + "popfq /* Replace current EFLAGS */\n\t" + "pushfq /* Read back the EFLAGS */\n\t" + "popq %%rax /* Get EFLAGS into EAX */\n\t" + "xorq %%rcx, %%rax /* Check if flag could be modified */\n\t" + : "=a" (id_supported) + : /* No inputs. */ + : /* Clobbered: */ "%rcx"); + + return id_supported != 0; +} + +#else + +static __inline int +grub_cpu_is_cpuid_supported (void) +{ + grub_uint32_t id_supported; + + __asm__ ("pushfl\n\t" + "popl %%eax /* Get EFLAGS into EAX */\n\t" + "movl %%eax, %%ecx /* Save original flags in ECX */\n\t" + "xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t" + "pushl %%eax /* Store modified EFLAGS on stack */\n\t" + "popfl /* Replace current EFLAGS */\n\t" + "pushfl /* Read back the EFLAGS */\n\t" + "popl %%eax /* Get EFLAGS into EAX */\n\t" + "xorl %%ecx, %%eax /* Check if flag could be modified */\n\t" + : "=a" (id_supported) + : /* No inputs. */ + : /* Clobbered: */ "%rcx"); + + return id_supported != 0; +} + +#endif + +static __inline int +grub_cpu_is_tsc_supported (void) +{ + if (! grub_cpu_is_cpuid_supported ()) + return 0; + + grub_uint32_t features; + __asm__ ("movl $1, %%eax\n\t" + "cpuid" + : "=d" (features) + : /* No inputs. */ + : /* Clobbered: */ "%rax", "%rbx", "%rcx"); + return (features & (1 << 4)) != 0; +} + +void grub_tsc_init (void); +grub_uint64_t grub_tsc_get_time_ms (void); + +#endif /* ! KERNEL_CPU_TSC_HEADER */ diff --git a/include/grub/i386/types.h b/include/grub/i386/types.h new file mode 100644 index 0000000..0ac6473 --- /dev/null +++ b/include/grub/i386/types.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 4 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 4 + +/* i386 is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h new file mode 100644 index 0000000..f17fc01 --- /dev/null +++ b/include/grub/i386/vga_common.h @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VGA_COMMON_CPU_HEADER +#define GRUB_VGA_COMMON_CPU_HEADER 1 + +#include +#include +#include + +extern grub_uint8_t grub_console_cur_color; + +void grub_console_putchar (grub_uint32_t c); +grub_ssize_t grub_console_getcharwidth (grub_uint32_t c); +grub_uint16_t grub_console_getwh (void); +void grub_console_setcolorstate (grub_term_color_state state); +void grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color); +void grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color); + +/* Implemented in both kern/i386/pc/startup.S and vga_text.c; this symbol + is not exported, so there's no collision, but vga_common.c expects this + prototype to be the same. */ +void grub_console_real_putchar (int c); + +#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */ diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h new file mode 100644 index 0000000..628d888 --- /dev/null +++ b/include/grub/ieee1275/ieee1275.h @@ -0,0 +1,177 @@ +/* ieee1275.h - Access the Open Firmware client interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_IEEE1275_HEADER +#define GRUB_IEEE1275_HEADER 1 + +#include +#include +#include +#include + +/* Maps a device alias to a pathname. */ +struct grub_ieee1275_devalias +{ + char *name; + char *path; + char *type; +}; + +struct grub_ieee1275_mem_region +{ + unsigned int start; + unsigned int size; +}; + +#ifndef IEEE1275_CALL_ENTRY_FN +#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args) +#endif + +/* All backcalls to the firmware is done by calling an entry function + which was passed to us from the bootloader. When doing the backcall, + a structure is passed which specifies what the firmware should do. + NAME is the requested service. NR_INS and NR_OUTS is the number of + passed arguments and the expected number of return values, resp. */ +struct grub_ieee1275_common_hdr +{ + grub_ieee1275_cell_t name; + grub_ieee1275_cell_t nr_ins; + grub_ieee1275_cell_t nr_outs; +}; + +#define INIT_IEEE1275_COMMON(p, xname, xins, xouts) \ + (p)->name = (grub_ieee1275_cell_t) xname; \ + (p)->nr_ins = (grub_ieee1275_cell_t) xins; \ + (p)->nr_outs = (grub_ieee1275_cell_t) xouts + +typedef grub_ieee1275_cell_t grub_ieee1275_ihandle_t; +typedef grub_ieee1275_cell_t grub_ieee1275_phandle_t; + +extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); +extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); +extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *); + +enum grub_ieee1275_flag +{ + /* Old World Macintosh firmware fails seek when "dev:0" is opened. */ + GRUB_IEEE1275_FLAG_NO_PARTITION_0, + + /* Apple firmware runs in translated mode and requires use of the "map" + method. Other firmware runs in untranslated mode and doesn't like "map" + calls. */ + GRUB_IEEE1275_FLAG_REAL_MODE, + + /* CHRP specifies partitions are numbered from 1 (partition 0 refers to the + whole disk). However, CodeGen firmware numbers partitions from 0. */ + GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS, + + /* CodeGen firmware does not correctly implement "output-device output" */ + GRUB_IEEE1275_FLAG_BROKEN_OUTPUT, + + /* OLPC / XO firmware hangs when accessing USB devices. */ + GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY, + + /* Open Hack'Ware stops when trying to set colors */ + GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS, + + /* Open Hack'Ware stops when grub_ieee1275_interpret is used. */ + GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, + + /* Open Hack'Ware has no memory map, just claim what we need. */ + GRUB_IEEE1275_FLAG_FORCE_CLAIM, + + /* Open Hack'Ware don't support the ANSI sequence. */ + GRUB_IEEE1275_FLAG_NO_ANSI, +}; + +extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); +extern void EXPORT_FUNC(grub_ieee1275_set_flag) (enum grub_ieee1275_flag flag); + + + + +void EXPORT_FUNC(grub_ieee1275_init) (void); +int EXPORT_FUNC(grub_ieee1275_finddevice) (char *name, + grub_ieee1275_phandle_t *phandlep); +int EXPORT_FUNC(grub_ieee1275_get_property) (grub_ieee1275_phandle_t phandle, + const char *property, void *buf, + grub_size_t size, + grub_ssize_t *actual); +int EXPORT_FUNC(grub_ieee1275_get_integer_property) (grub_ieee1275_phandle_t phandle, + const char *property, grub_uint32_t *buf, + grub_size_t size, + grub_ssize_t *actual); +int EXPORT_FUNC(grub_ieee1275_next_property) (grub_ieee1275_phandle_t phandle, + char *prev_prop, char *prop); +int EXPORT_FUNC(grub_ieee1275_get_property_length) + (grub_ieee1275_phandle_t phandle, const char *prop, grub_ssize_t *length); +int EXPORT_FUNC(grub_ieee1275_instance_to_package) + (grub_ieee1275_ihandle_t ihandle, grub_ieee1275_phandle_t *phandlep); +int EXPORT_FUNC(grub_ieee1275_package_to_path) (grub_ieee1275_phandle_t phandle, + char *path, grub_size_t len, + grub_ssize_t *actual); +int EXPORT_FUNC(grub_ieee1275_instance_to_path) + (grub_ieee1275_ihandle_t ihandle, char *path, grub_size_t len, + grub_ssize_t *actual); +int EXPORT_FUNC(grub_ieee1275_write) (grub_ieee1275_ihandle_t ihandle, + void *buffer, grub_size_t len, + grub_ssize_t *actualp); +int EXPORT_FUNC(grub_ieee1275_read) (grub_ieee1275_ihandle_t ihandle, + void *buffer, grub_size_t len, + grub_ssize_t *actualp); +int EXPORT_FUNC(grub_ieee1275_seek) (grub_ieee1275_ihandle_t ihandle, + int pos_hi, int pos_lo, + grub_ssize_t *result); +int EXPORT_FUNC(grub_ieee1275_peer) (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result); +int EXPORT_FUNC(grub_ieee1275_child) (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result); +int EXPORT_FUNC(grub_ieee1275_parent) (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result); +int EXPORT_FUNC(grub_ieee1275_interpret) (const char *command, + grub_ieee1275_cell_t *catch); +int EXPORT_FUNC(grub_ieee1275_enter) (void); +void EXPORT_FUNC(grub_ieee1275_exit) (void) __attribute__ ((noreturn)); +int EXPORT_FUNC(grub_ieee1275_open) (const char *node, + grub_ieee1275_ihandle_t *result); +int EXPORT_FUNC(grub_ieee1275_close) (grub_ieee1275_ihandle_t ihandle); +int EXPORT_FUNC(grub_ieee1275_claim) (grub_addr_t addr, grub_size_t size, + unsigned int align, grub_addr_t *result); +int EXPORT_FUNC(grub_ieee1275_release) (grub_addr_t addr, grub_size_t size); +int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle, + const char *propname, void *buf, + grub_size_t size, + grub_ssize_t *actual); +int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, + int index, int r, int g, int b); +int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs); + + +grub_err_t EXPORT_FUNC(grub_devalias_iterate) + (int (*hook) (struct grub_ieee1275_devalias *alias)); +grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath, + int (*hook) (struct grub_ieee1275_devalias *alias)); +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); + +char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path); +char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); + +#endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h new file mode 100644 index 0000000..2f69e3f --- /dev/null +++ b/include/grub/ieee1275/ofdisk.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_OFDISK_HEADER +#define GRUB_OFDISK_HEADER 1 + +extern void grub_ofdisk_init (void); +extern void grub_ofdisk_fini (void); + +#endif /* ! GRUB_INIT_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h new file mode 100644 index 0000000..adaee58 --- /dev/null +++ b/include/grub/kernel.h @@ -0,0 +1,75 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_HEADER +#define GRUB_KERNEL_HEADER 1 + +#include +#include + +/* The module header. */ +struct grub_module_header +{ + /* The type of object. */ + grub_int8_t type; + enum + { + OBJ_TYPE_ELF, + OBJ_TYPE_MEMDISK, + } grub_module_header_types; + + /* The size of object (including this header). */ + grub_target_size_t size; +}; + +/* "gmim" (GRUB Module Info Magic). */ +#define GRUB_MODULE_MAGIC 0x676d696d + +struct grub_module_info +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + grub_uint32_t padding; +#endif + /* The offset of the modules. */ + grub_target_off_t offset; + /* The size of all modules plus this header. */ + grub_target_size_t size; +}; + +extern grub_addr_t grub_arch_modules_addr (void); + +extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); + +/* The start point of the C code. */ +void grub_main (void); + +/* The machine-specific initialization. This must initialize memory. */ +void grub_machine_init (void); + +/* The machine-specific finalization. */ +void grub_machine_fini (void); + +/* The machine-specific prefix initialization. */ +void grub_machine_set_prefix (void); + +/* Register all the exported symbols. This is automatically generated. */ +void grub_register_exported_symbols (void); + +#endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/lib/LzFind.h b/include/grub/lib/LzFind.h new file mode 100644 index 0000000..69447b6 --- /dev/null +++ b/include/grub/lib/LzFind.h @@ -0,0 +1,130 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZFIND_H +#define __LZFIND_H + +#include + +typedef UInt32 CLzRef; + +typedef struct _CMatchFinder +{ + Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufferBase; + ISeqInStream *stream; + int streamEndWasReached; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + int directInput; + int btMode; + /* int skipModeBits; */ + int bigHash; + UInt32 historySize; + UInt32 fixedHashSize; + UInt32 hashSizeSum; + UInt32 numSons; + SRes result; + UInt32 crc[256]; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) +#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) + +int MatchFinder_NeedMove(CMatchFinder *p); +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* Conditions: + historySize <= 3 GB + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +*/ +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct _IMatchFinder +{ + Mf_Init_Func Init; + Mf_GetIndexByte_Func GetIndexByte; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); + +void MatchFinder_Init(CMatchFinder *p); +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +#endif diff --git a/include/grub/lib/LzHash.h b/include/grub/lib/LzHash.h new file mode 100644 index 0000000..c3d5586 --- /dev/null +++ b/include/grub/lib/LzHash.h @@ -0,0 +1,77 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZHASH_H +#define __LZHASH_H + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +#define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); + +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ + hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ + hash4Value &= (kHash4Size - 1); } + +/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +#define MT_HASH2_CALC \ + hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } + +#endif diff --git a/include/grub/lib/LzmaDec.h b/include/grub/lib/LzmaDec.h new file mode 100644 index 0000000..1e66b74 --- /dev/null +++ b/include/grub/lib/LzmaDec.h @@ -0,0 +1,246 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZMADEC_H +#define __LZMADEC_H + +#include "Types.h" + +/* #define _LZMA_PROB32 */ +/* _LZMA_PROB32 can increase the speed on some CPUs, + but memory usage for CLzmaDec::probs will be doubled in that case */ + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaProps +{ + unsigned lc, lp, pb; + UInt32 dicSize; +} CLzmaProps; + +/* LzmaProps_Decode - decodes properties +Returns: + SZ_OK + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); + + +/* ---------- LZMA Decoder state ---------- */ + +/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + +typedef struct +{ + CLzmaProps prop; + CLzmaProb *probs; + Byte *dic; + const Byte *buf; + UInt32 range, code; + SizeT dicPos; + SizeT dicBufSize; + UInt32 processedPos; + UInt32 checkDicSize; + unsigned state; + UInt32 reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + UInt32 numProbs; + unsigned tempBufSize; + Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +} CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + +void LzmaDec_Init(CLzmaDec *p); + +/* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + +typedef enum +{ + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ +} ELzmaFinishMode; + +/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + +typedef enum +{ + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +} ELzmaStatus; + +/* ELzmaStatus is used only as output value for function call */ + + +/* ---------- Interfaces ---------- */ + +/* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + +/* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + +LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + +SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + +/* ---------- Dictionary Interface ---------- */ + +/* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + + STEPS: + LzmaDec_Constr() + LzmaDec_Allocate() + for (each new stream) + { + LzmaDec_Init() + while (it needs more decompression) + { + LzmaDec_DecodeToDic() + use data from CLzmaDec::dic and update CLzmaDec::dicPos + } + } + LzmaDec_Free() +*/ + +/* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: + It has meaning only if the decoding reaches output limit (dicLimit). + LZMA_FINISH_ANY - Decode just dicLimit bytes. + LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error +*/ + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#endif diff --git a/include/grub/lib/LzmaEnc.h b/include/grub/lib/LzmaEnc.h new file mode 100644 index 0000000..c625cd0 --- /dev/null +++ b/include/grub/lib/LzmaEnc.h @@ -0,0 +1,95 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZMAENC_H +#define __LZMAENC_H + +#include "LzmaTypes.h" + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (1 << 30) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc_* functions can return the following exit codes: +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +/* ---------- One Call Interface ---------- */ + +/* LzmaEncode +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +#endif diff --git a/include/grub/lib/LzmaTypes.h b/include/grub/lib/LzmaTypes.h new file mode 100644 index 0000000..1e783a2 --- /dev/null +++ b/include/grub/lib/LzmaTypes.h @@ -0,0 +1,151 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +#ifdef _LZMA_UINT32_IS_ULONG +typedef long Int32; +typedef unsigned long UInt32; +#else +typedef int Int32; +typedef unsigned int UInt32; +#endif + +/* #define _SZ_NO_INT_64 */ +/* define it if your compiler doesn't support 64-bit integers */ + +#ifdef _SZ_NO_INT_64 + +typedef long Int64; +typedef unsigned long UInt64; + +#else + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif + +#endif + +#ifdef _LZMA_NO_SYSTEM_SIZE_T +typedef UInt32 SizeT; +#else +#include +typedef size_t SizeT; +#endif + +typedef int Bool; +#define True 1 +#define False 0 + + +#ifdef _MSC_VER + +#if _MSC_VER >= 1300 +#define MY_NO_INLINE __declspec(noinline) +#else +#define MY_NO_INLINE +#endif + +#define MY_CDECL __cdecl +#define MY_STD_CALL __stdcall +#define MY_FAST_CALL MY_NO_INLINE __fastcall + +#else + +#define MY_CDECL +#define MY_STD_CALL +#define MY_FAST_CALL + +#endif + + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +typedef struct +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef struct +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + +#endif diff --git a/include/grub/lib/crc.h b/include/grub/lib/crc.h new file mode 100644 index 0000000..ff7284d --- /dev/null +++ b/include/grub/lib/crc.h @@ -0,0 +1,25 @@ +/* crc.h - prototypes for crc */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CRC_H +#define GRUB_CRC_H 1 + +grub_uint32_t grub_getcrc32 (grub_uint32_t crc, void *buf, int size); + +#endif /* ! GRUB_CRC_H */ diff --git a/include/grub/lib/datetime.h b/include/grub/lib/datetime.h new file mode 100644 index 0000000..7b140cc --- /dev/null +++ b/include/grub/lib/datetime.h @@ -0,0 +1,44 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_DATETIME_HEADER +#define KERNEL_DATETIME_HEADER 1 + +#include +#include + +struct grub_datetime +{ + grub_uint16_t year; + grub_uint8_t month; + grub_uint8_t day; + grub_uint8_t hour; + grub_uint8_t minute; + grub_uint8_t second; +}; + +/* Return date and time. */ +grub_err_t grub_get_datetime (struct grub_datetime *datetime); + +/* Set date and time. */ +grub_err_t grub_set_datetime (struct grub_datetime *datetime); + +int grub_get_weekday (struct grub_datetime *datetime); +char *grub_get_weekday_name (struct grub_datetime *datetime); + +#endif /* ! KERNEL_DATETIME_HEADER */ diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h new file mode 100644 index 0000000..5c1157e --- /dev/null +++ b/include/grub/lib/envblk.h @@ -0,0 +1,45 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ENVBLK_HEADER +#define GRUB_ENVBLK_HEADER 1 + +#define GRUB_ENVBLK_SIGNATURE 0x764e6547 /* GeNv */ + +#define GRUB_ENVBLK_MAXLEN 8192 + +#define GRUB_ENVBLK_DEFCFG "grubenv" + +#ifndef ASM_FILE + +struct grub_envblk +{ + grub_uint32_t signature; + grub_uint16_t length; + char data[0]; +} __attribute__ ((packed)); +typedef struct grub_envblk *grub_envblk_t; + +grub_envblk_t grub_envblk_find (char *buf); +int grub_envblk_insert (grub_envblk_t envblk, char *name, char *value); +void grub_envblk_delete (grub_envblk_t envblk, char *name); +void grub_envblk_iterate (grub_envblk_t envblk, int hook (char *name, char *value)); + +#endif + +#endif /* ! GRUB_ENVBLK_HEADER */ diff --git a/include/grub/lib/hexdump.h b/include/grub/lib/hexdump.h new file mode 100644 index 0000000..23c6fa6 --- /dev/null +++ b/include/grub/lib/hexdump.h @@ -0,0 +1,25 @@ +/* hexdump.h - prototypes for dump */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_HEXDUMP_H +#define GRUB_HEXDUMP_H 1 + +void hexdump (unsigned long bse,char* buf,int len); + +#endif /* ! GRUB_HEXDUMP_H */ diff --git a/include/grub/loader.h b/include/grub/loader.h new file mode 100644 index 0000000..1ae5fdd --- /dev/null +++ b/include/grub/loader.h @@ -0,0 +1,44 @@ +/* loader.h - OS loaders */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_HEADER +#define GRUB_LOADER_HEADER 1 + +#include +#include +#include +#include + +/* Check if a loader is loaded. */ +int EXPORT_FUNC(grub_loader_is_loaded) (void); + +/* Set loader functions. NORETURN must be set to true, if BOOT won't return + to the original state. */ +void EXPORT_FUNC(grub_loader_set) (grub_err_t (*boot) (void), + grub_err_t (*unload) (void), + int noreturn); + +/* Unset current loader, if any. */ +void EXPORT_FUNC(grub_loader_unset) (void); + +/* Call the boot hook in current loader. This may or may not return, + depending on the setting by grub_loader_set. */ +grub_err_t EXPORT_FUNC(grub_loader_boot) (void); + +#endif /* ! GRUB_LOADER_HEADER */ diff --git a/include/grub/lvm.h b/include/grub/lvm.h new file mode 100644 index 0000000..dd91cc6 --- /dev/null +++ b/include/grub/lvm.h @@ -0,0 +1,129 @@ +/* lvm.h - On disk structures for LVM. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LVM_H +#define GRUB_LVM_H 1 + +#include + +/* Length of ID string, excluding terminating zero. */ +#define GRUB_LVM_ID_STRLEN 38 + +struct grub_lvm_vg { + char id[GRUB_LVM_ID_STRLEN+1]; + char *name; + int extent_size; + struct grub_lvm_pv *pvs; + struct grub_lvm_lv *lvs; + struct grub_lvm_vg *next; +}; + +struct grub_lvm_pv { + char id[GRUB_LVM_ID_STRLEN+1]; + char *name; + grub_disk_t disk; + int start; /* Sector number where the data area starts. */ + struct grub_lvm_pv *next; +}; + +struct grub_lvm_lv { + char *name; + unsigned int number; + unsigned int segment_count; + grub_uint64_t size; + struct grub_lvm_segment *segments; /* Pointer to segment_count segments. */ + struct grub_lvm_vg *vg; + struct grub_lvm_lv *next; +}; + +struct grub_lvm_segment { + unsigned int start_extent; + unsigned int extent_count; + unsigned int stripe_count; + unsigned int stripe_size; + struct grub_lvm_stripe *stripes; /* Pointer to stripe_count stripes. */ +}; + +struct grub_lvm_stripe { + int start; + struct grub_lvm_pv *pv; +}; + +#define GRUB_LVM_LABEL_SIZE GRUB_DISK_SECTOR_SIZE +#define GRUB_LVM_LABEL_SCAN_SECTORS 4L + +#define GRUB_LVM_LABEL_ID "LABELONE" +#define GRUB_LVM_LVM2_LABEL "LVM2 001" + +#define GRUB_LVM_ID_LEN 32 + +/* On disk - 32 bytes */ +struct grub_lvm_label_header { + grub_int8_t id[8]; /* LABELONE */ + grub_uint64_t sector_xl; /* Sector number of this label */ + grub_uint32_t crc_xl; /* From next field to end of sector */ + grub_uint32_t offset_xl; /* Offset from start of struct to contents */ + grub_int8_t type[8]; /* LVM2 001 */ +} __attribute__ ((packed)); + +/* On disk */ +struct grub_lvm_disk_locn { + grub_uint64_t offset; /* Offset in bytes to start sector */ + grub_uint64_t size; /* Bytes */ +} __attribute__ ((packed)); + +/* Fields with the suffix _xl should be xlate'd wherever they appear */ +/* On disk */ +struct grub_lvm_pv_header { + grub_int8_t pv_uuid[GRUB_LVM_ID_LEN]; + + /* This size can be overridden if PV belongs to a VG */ + grub_uint64_t device_size_xl; /* Bytes */ + + /* NULL-terminated list of data areas followed by */ + /* NULL-terminated list of metadata area headers */ + struct grub_lvm_disk_locn disk_areas_xl[0]; /* Two lists */ +} __attribute__ ((packed)); + +#define GRUB_LVM_FMTT_MAGIC "\040\114\126\115\062\040\170\133\065\101\045\162\060\116\052\076" +#define GRUB_LVM_FMTT_VERSION 1 +#define GRUB_LVM_MDA_HEADER_SIZE 512 + +/* On disk */ +struct grub_lvm_raw_locn { + grub_uint64_t offset; /* Offset in bytes to start sector */ + grub_uint64_t size; /* Bytes */ + grub_uint32_t checksum; + grub_uint32_t filler; +} __attribute__ ((packed)); + +/* On disk */ +/* Structure size limited to one sector */ +struct grub_lvm_mda_header { + grub_uint32_t checksum_xl; /* Checksum of rest of mda_header */ + grub_int8_t magic[16]; /* To aid scans for metadata */ + grub_uint32_t version; + grub_uint64_t start; /* Absolute start byte of mda_header */ + grub_uint64_t size; /* Size of metadata area */ + + struct grub_lvm_raw_locn raw_locns[0]; /* NULL-terminated list */ +} __attribute__ ((packed)); + + +#endif /* ! GRUB_LVM_H */ diff --git a/include/grub/menu.h b/include/grub/menu.h new file mode 100644 index 0000000..6850846 --- /dev/null +++ b/include/grub/menu.h @@ -0,0 +1,63 @@ +/* menu.h - Menu and menu entry model declarations. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MENU_HEADER +#define GRUB_MENU_HEADER 1 + +struct grub_menu_entry_class +{ + char *name; + struct grub_menu_entry_class *next; +}; + +/* The menu entry. */ +struct grub_menu_entry +{ + /* The title name. */ + const char *title; + + /* The classes associated with the menu entry: + used to choose an icon or other style attributes. + This is a dummy head node for the linked list, so for an entry E, + E.classes->next is the first class if it is not NULL. */ + struct grub_menu_entry_class *classes; + + /* The commands associated with this menu entry. */ + struct grub_script *commands; + + /* The sourcecode of the menu entry, used by the editor. */ + const char *sourcecode; + + /* The next element. */ + struct grub_menu_entry *next; +}; +typedef struct grub_menu_entry *grub_menu_entry_t; + +/* The menu. */ +struct grub_menu +{ + /* The size of a menu. */ + int size; + + /* The list of menu entries. */ + grub_menu_entry_t entry_list; +}; +typedef struct grub_menu *grub_menu_t; + +#endif /* GRUB_MENU_HEADER */ diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h new file mode 100644 index 0000000..725c975 --- /dev/null +++ b/include/grub/menu_viewer.h @@ -0,0 +1,43 @@ +/* menu_viewer.h - Interface to menu viewer implementations. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MENU_VIEWER_HEADER +#define GRUB_MENU_VIEWER_HEADER 1 + +#include +#include +#include +#include + +struct grub_menu_viewer +{ + /* The menu viewer name. */ + const char *name; + + grub_err_t (*show_menu) (grub_menu_t menu, int nested); + + struct grub_menu_viewer *next; +}; +typedef struct grub_menu_viewer *grub_menu_viewer_t; + +void grub_menu_viewer_register (grub_menu_viewer_t viewer); + +grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested); + +#endif /* GRUB_MENU_VIEWER_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h new file mode 100644 index 0000000..c377c20 --- /dev/null +++ b/include/grub/misc.h @@ -0,0 +1,119 @@ +/* misc.h - prototypes for misc functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MISC_HEADER +#define GRUB_MISC_HEADER 1 + +#include +#include +#include +#include + +#define ALIGN_UP(addr, align) (((grub_uint64_t)addr + align - 1) & ~(align - 1)) + +#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__FILE__, __LINE__, condition, fmt, ## args); +/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ +#define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n)) + +void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); +char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); +char *EXPORT_FUNC(grub_strncpy) (char *dest, const char *src, int c); +char *EXPORT_FUNC(grub_stpcpy) (char *dest, const char *src); +char *EXPORT_FUNC(grub_strcat) (char *dest, const char *src); +char *EXPORT_FUNC(grub_strncat) (char *dest, const char *src, int c); + +/* Prototypes for aliases. */ +void *EXPORT_FUNC(memmove) (void *dest, const void *src, grub_size_t n); +void *EXPORT_FUNC(memcpy) (void *dest, const void *src, grub_size_t n); + +int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n); +int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2); +int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); +int EXPORT_FUNC(grub_strcasecmp) (const char *s1, const char *s2); +int EXPORT_FUNC(grub_strncasecmp) (const char *s1, const char *s2, grub_size_t n); +char *EXPORT_FUNC(grub_strchr) (const char *s, int c); +char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); +int EXPORT_FUNC(grub_strword) (const char *s, const char *w); +char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); +int EXPORT_FUNC(grub_iswordseparator) (int c); +int EXPORT_FUNC(grub_isspace) (int c); +int EXPORT_FUNC(grub_isprint) (int c); +int EXPORT_FUNC(grub_isalpha) (int c); +int EXPORT_FUNC(grub_isgraph) (int c); +int EXPORT_FUNC(grub_isdigit) (int c); +int EXPORT_FUNC(grub_tolower) (int c); +unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); +unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); +char *EXPORT_FUNC(grub_strdup) (const char *s); +char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n); +void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); +grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); +int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +void EXPORT_FUNC(grub_real_dprintf) (const char *file, + const int line, + const char *condition, + const char *fmt, ...) __attribute__ ((format (printf, 4, 5))); +int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); +int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); +void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); +grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest, + grub_uint16_t *src, + grub_size_t size); +grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, + grub_size_t destsize, + const grub_uint8_t *src, + grub_size_t srcsize, + const grub_uint8_t **srcend); +grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint32_t d, grub_uint32_t *r); + +#ifdef NEED_ENABLE_EXECUTE_STACK +void EXPORT_FUNC(__enable_execute_stack) (void *addr); +#endif + +/* Inline functions. */ + +static inline unsigned int +grub_abs (int x) +{ + if (x < 0) + return (unsigned int) (-x); + else + return (unsigned int) x; +} + +static inline long +grub_max (long x, long y) +{ + if (x > y) + return x; + else + return y; +} + +/* Rounded-up division */ +static inline unsigned int +grub_div_roundup (unsigned int x, unsigned int y) +{ + return (x + y - 1) / y; +} + +#endif /* ! GRUB_MISC_HEADER */ diff --git a/include/grub/mm.h b/include/grub/mm.h new file mode 100644 index 0000000..4dd1363 --- /dev/null +++ b/include/grub/mm.h @@ -0,0 +1,66 @@ +/* mm.h - prototypes and declarations for memory manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MM_H +#define GRUB_MM_H 1 + +#include +#include +#include + +#ifndef NULL +# define NULL ((void *) 0) +#endif + +void grub_mm_init_region (void *addr, grub_size_t size); +void *EXPORT_FUNC(grub_malloc) (grub_size_t size); +void EXPORT_FUNC(grub_free) (void *ptr); +void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); +void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); + +/* For debugging. */ +#if defined(MM_DEBUG) && !defined(GRUB_UTIL) +/* Set this variable to 1 when you want to trace all memory function calls. */ +extern int EXPORT_VAR(grub_mm_debug); + +void grub_mm_dump_free (void); +void grub_mm_dump (unsigned lineno); + +#define grub_malloc(size) \ + grub_debug_malloc (__FILE__, __LINE__, size) + +#define grub_realloc(ptr,size) \ + grub_debug_realloc (__FILE__, __LINE__, ptr, size) + +#define grub_memalign(align,size) \ + grub_debug_memalign (__FILE__, __LINE__, align, size) + +#define grub_free(ptr) \ + grub_debug_free (__FILE__, __LINE__, ptr) + +void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line, + grub_size_t size); +void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr); +void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr, + grub_size_t size); +void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line, + grub_size_t align, grub_size_t size); +#endif /* MM_DEBUG && ! GRUB_UTIL */ + +#endif /* ! GRUB_MM_H */ diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h new file mode 100644 index 0000000..5285ea2 --- /dev/null +++ b/include/grub/multiboot.h @@ -0,0 +1,129 @@ +/* multiboot.h - multiboot header file with grub definitions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MULTIBOOT_HEADER +#define GRUB_MULTIBOOT_HEADER 1 + +#include + +void grub_multiboot (int argc, char *argv[]); +void grub_module (int argc, char *argv[]); + +#ifndef ASM_FILE + +#include + +struct grub_multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + grub_uint32_t magic; + + /* Feature flags. */ + grub_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + grub_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + grub_uint32_t header_addr; + grub_uint32_t load_addr; + grub_uint32_t load_end_addr; + grub_uint32_t bss_end_addr; + grub_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + grub_uint32_t mode_type; + grub_uint32_t width; + grub_uint32_t height; + grub_uint32_t depth; +}; + +struct grub_multiboot_info +{ + /* Multiboot info version number */ + grub_uint32_t flags; + + /* Available memory from BIOS */ + grub_uint32_t mem_lower; + grub_uint32_t mem_upper; + + /* "root" partition */ + grub_uint32_t boot_device; + + /* Kernel command line */ + grub_uint32_t cmdline; + + /* Boot-Module list */ + grub_uint32_t mods_count; + grub_uint32_t mods_addr; + + grub_uint32_t syms[4]; + + /* Memory Mapping buffer */ + grub_uint32_t mmap_length; + grub_uint32_t mmap_addr; + + /* Drive Info buffer */ + grub_uint32_t drives_length; + grub_uint32_t drives_addr; + + /* ROM configuration table */ + grub_uint32_t config_table; + + /* Boot Loader Name */ + grub_uint32_t boot_loader_name; + + /* APM table */ + grub_uint32_t apm_table; + + /* Video */ + grub_uint32_t vbe_control_info; + grub_uint32_t vbe_mode_info; + grub_uint16_t vbe_mode; + grub_uint16_t vbe_interface_seg; + grub_uint16_t vbe_interface_off; + grub_uint16_t vbe_interface_len; +}; + +struct grub_multiboot_mmap_entry +{ + grub_uint32_t size; + grub_uint64_t addr; + grub_uint64_t len; +#define GRUB_MULTIBOOT_MEMORY_AVAILABLE 1 +#define GRUB_MULTIBOOT_MEMORY_RESERVED 2 + grub_uint32_t type; +} __attribute__((packed)); + +struct grub_mod_list +{ + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + grub_uint32_t mod_start; + grub_uint32_t mod_end; + + /* Module command line */ + grub_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + grub_uint32_t pad; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h new file mode 100644 index 0000000..bfbffcc --- /dev/null +++ b/include/grub/multiboot2.h @@ -0,0 +1,64 @@ +/* multiboot2.h - multiboot2 header file with grub definitions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MULTIBOOT2_HEADER +#define GRUB_MULTIBOOT2_HEADER 1 + +#include +#include +#include + +struct multiboot_tag_header; + +grub_err_t +grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len); + +grub_err_t +grub_mb2_tags_arch_create (void); + +void +grub_mb2_arch_boot (grub_addr_t entry, void *tags); + +void +grub_mb2_arch_unload (struct multiboot_tag_header *tags); + +grub_err_t +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr); + +grub_err_t +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr); + +grub_err_t +grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr); + +grub_err_t +grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size); + +void +grub_multiboot2 (int argc, char *argv[]); + +void +grub_module2 (int argc, char *argv[]); + +#define for_each_tag(tag, tags) \ + for (tag = tags; \ + tag && tag->key != MULTIBOOT2_TAG_END; \ + tag = (struct multiboot_tag_header *)((char *)tag + tag->len)) + +#endif /* ! GRUB_MULTIBOOT2_HEADER */ diff --git a/include/grub/multiboot_loader.h b/include/grub/multiboot_loader.h new file mode 100644 index 0000000..bf1c130 --- /dev/null +++ b/include/grub/multiboot_loader.h @@ -0,0 +1,28 @@ +/* multiboot_loader.h - multiboot loader header file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + +#ifndef GRUB_MULTIBOOT_LOADER_HEADER +#define GRUB_MULTIBOOT_LOADER_HEADER 1 + +/* Provided by the core ("rescue mode"). */ +void grub_rescue_cmd_multiboot_loader (int argc, char *argv[]); +void grub_rescue_cmd_module_loader (int argc, char *argv[]); + +#endif /* ! GRUB_MULTIBOOT_LOADER_HEADER */ diff --git a/include/grub/net.h b/include/grub/net.h new file mode 100644 index 0000000..2eac431 --- /dev/null +++ b/include/grub/net.h @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_NET_HEADER +#define GRUB_NET_HEADER 1 + +#include +#include +#include + +struct grub_net; + +struct grub_net_dev +{ + /* The device name. */ + const char *name; + + /* FIXME: Just a template. */ + int (*probe) (struct grub_net *net, const void *addr); + void (*reset) (struct grub_net *net); + int (*poll) (struct grub_net *net); + void (*transmit) (struct grub_net *net, const void *destip, + unsigned srcsock, unsigned destsock, const void *packet); + void (*disable) (struct grub_net *net); + + /* The next net device. */ + struct grub_net_dev *next; +}; +typedef struct grub_net_dev *grub_net_dev_t; + +struct grub_fs; + +struct grub_net +{ + /* The net name. */ + const char *name; + + /* The underlying disk device. */ + grub_net_dev_t dev; + + /* The binding filesystem. */ + struct grub_fs *fs; + + /* FIXME: More data would be required, such as an IP address, a mask, + a gateway, etc. */ + + /* Device-specific data. */ + void *data; +}; +typedef struct grub_net *grub_net_t; + +/* FIXME: How to abstract networks? More consideration is necessary. */ + +/* Note: Networks are very different from disks, because networks must + be initialized before used, and the status is persistent. */ + +#endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/normal.h b/include/grub/normal.h new file mode 100644 index 0000000..216ae0d --- /dev/null +++ b/include/grub/normal.h @@ -0,0 +1,198 @@ +/* normal.h - prototypes for the normal mode */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_NORMAL_HEADER +#define GRUB_NORMAL_HEADER 1 + +#include +#include +#include +#include +#include +#include + +/* The maximum size of a command-line. */ +#define GRUB_MAX_CMDLINE 1600 + +/* Can be run in the command-line. */ +#define GRUB_COMMAND_FLAG_CMDLINE 0x1 +/* Can be run in the menu. */ +#define GRUB_COMMAND_FLAG_MENU 0x2 +/* Can be run in both interfaces. */ +#define GRUB_COMMAND_FLAG_BOTH 0x3 +/* Only for the command title. */ +#define GRUB_COMMAND_FLAG_TITLE 0x4 +/* Don't print the command on booting. */ +#define GRUB_COMMAND_FLAG_NO_ECHO 0x8 +/* Pass arguments to the command without parsing options. */ +#define GRUB_COMMAND_FLAG_NO_ARG_PARSE 0x10 +/* Not loaded yet. Used for auto-loading. */ +#define GRUB_COMMAND_FLAG_NOT_LOADED 0x20 + +/* The type of a completion item. */ +enum grub_completion_type + { + GRUB_COMPLETION_TYPE_COMMAND, + GRUB_COMPLETION_TYPE_DEVICE, + GRUB_COMPLETION_TYPE_PARTITION, + GRUB_COMPLETION_TYPE_FILE, + GRUB_COMPLETION_TYPE_ARGUMENT + }; +typedef enum grub_completion_type grub_completion_type_t; + +/* The command description. */ +struct grub_command +{ + /* The name. */ + char *name; + + /* The callback function. */ + grub_err_t (*func) (struct grub_arg_list *state, int argc, char **args); + + /* The flags. */ + unsigned flags; + + /* The summary of the command usage. */ + const char *summary; + + /* The description of the command. */ + const char *description; + + /* The argument parser optionlist. */ + const struct grub_arg_option *options; + + /* The name of a module. Used for auto-loading. */ + char *module_name; + + /* The next element. */ + struct grub_command *next; +}; +typedef struct grub_command *grub_command_t; + +/* This is used to store the names of filesystem modules for auto-loading. */ +struct grub_fs_module_list +{ + char *name; + struct grub_fs_module_list *next; +}; +typedef struct grub_fs_module_list *grub_fs_module_list_t; + +/* To exit from the normal mode. */ +extern grub_jmp_buf grub_exit_env; + +extern struct grub_menu_viewer grub_normal_text_menu_viewer; + +/* Callback structure menu viewers can use to provide user feedback when + default entries are executed, possibly including fallback entries. */ +typedef struct grub_menu_execute_callback +{ + /* Called immediately before ENTRY is booted. */ + void (*notify_booting) (grub_menu_entry_t entry, void *userdata); + + /* Called when executing one entry has failed, and another entry, ENTRY, will + be executed as a fallback. The implementation of this function should + delay for a period of at least 2 seconds before returning in order to + allow the user time to read the information before it can be lost by + executing ENTRY. */ + void (*notify_fallback) (grub_menu_entry_t entry, void *userdata); + + /* Called when an entry has failed to execute and there is no remaining + fallback entry to attempt. */ + void (*notify_failure) (void *userdata); +} +*grub_menu_execute_callback_t; + +void grub_enter_normal_mode (const char *config); +void grub_normal_execute (const char *config, int nested); +void grub_menu_execute_with_fallback (grub_menu_t menu, + grub_menu_entry_t entry, + grub_menu_execute_callback_t callback, + void *callback_data); +void grub_menu_entry_run (grub_menu_entry_t entry); +void grub_menu_execute_entry(grub_menu_entry_t entry); +grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); +int grub_menu_get_timeout (void); +void grub_menu_set_timeout (int timeout); +void grub_cmdline_run (int nested); +int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, + int echo_char, int readline); +grub_command_t grub_register_command (const char *name, + grub_err_t (*func) (struct grub_arg_list *state, + int argc, + char **args), + unsigned flags, + const char *summary, + const char *description, + const struct grub_arg_option *parser); +void grub_unregister_command (const char *name); +grub_command_t grub_command_find (char *cmdline); +grub_err_t grub_set_history (int newsize); +int grub_iterate_commands (int (*iterate) (grub_command_t)); +int grub_command_execute (char *cmdline, int interactive); +void grub_command_init (void); +void grub_normal_init_page (void); +void grub_menu_init_page (int nested, int edit); +int grub_arg_parse (grub_command_t parser, int argc, char **argv, + struct grub_arg_list *usr, char ***args, int *argnum); +void grub_arg_show_help (grub_command_t cmd); +char *grub_normal_do_completion (char *buf, int *restore, + void (*hook) (const char *item, grub_completion_type_t type, int count)); +grub_err_t grub_normal_print_device_info (const char *name); +grub_err_t grub_normal_menu_addentry (int argc, const char **args, + struct grub_script *script, + const char *sourcecode); +char *grub_env_write_color_normal (struct grub_env_var *var, const char *val); +char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val); +void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); +void grub_wait_after_message (void); + +#ifdef GRUB_UTIL +void grub_normal_init (void); +void grub_normal_fini (void); +void grub_hello_init (void); +void grub_hello_fini (void); +void grub_ls_init (void); +void grub_ls_fini (void); +void grub_cat_init (void); +void grub_cat_fini (void); +void grub_boot_init (void); +void grub_boot_fini (void); +void grub_cmp_init (void); +void grub_cmp_fini (void); +void grub_terminal_init (void); +void grub_terminal_fini (void); +void grub_loop_init (void); +void grub_loop_fini (void); +void grub_help_init (void); +void grub_help_fini (void); +void grub_halt_init (void); +void grub_halt_fini (void); +void grub_reboot_init (void); +void grub_reboot_fini (void); +void grub_configfile_init (void); +void grub_configfile_fini (void); +void grub_search_init (void); +void grub_search_fini (void); +void grub_test_init (void); +void grub_test_fini (void); +void grub_blocklist_init (void); +void grub_blocklist_fini (void); +#endif + +#endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h new file mode 100644 index 0000000..9b2ae0a --- /dev/null +++ b/include/grub/ntfs.h @@ -0,0 +1,182 @@ +/* ntfs.h - header for the NTFS filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_NTFS_H +#define GRUB_NTFS_H 1 + +#define FILE_MFT 0 +#define FILE_MFTMIRR 1 +#define FILE_LOGFILE 2 +#define FILE_VOLUME 3 +#define FILE_ATTRDEF 4 +#define FILE_ROOT 5 +#define FILE_BITMAP 6 +#define FILE_BOOT 7 +#define FILE_BADCLUS 8 +#define FILE_QUOTA 9 +#define FILE_UPCASE 10 + +#define AT_STANDARD_INFORMATION 0x10 +#define AT_ATTRIBUTE_LIST 0x20 +#define AT_FILENAME 0x30 +#define AT_OBJECT_ID 0x40 +#define AT_SECURITY_DESCRIPTOR 0x50 +#define AT_VOLUME_NAME 0x60 +#define AT_VOLUME_INFORMATION 0x70 +#define AT_DATA 0x80 +#define AT_INDEX_ROOT 0x90 +#define AT_INDEX_ALLOCATION 0xA0 +#define AT_BITMAP 0xB0 +#define AT_SYMLINK 0xC0 +#define AT_EA_INFORMATION 0xD0 +#define AT_EA 0xE0 + +#define ATTR_READ_ONLY 0x1 +#define ATTR_HIDDEN 0x2 +#define ATTR_SYSTEM 0x4 +#define ATTR_ARCHIVE 0x20 +#define ATTR_DEVICE 0x40 +#define ATTR_NORMAL 0x80 +#define ATTR_TEMPORARY 0x100 +#define ATTR_SPARSE 0x200 +#define ATTR_REPARSE 0x400 +#define ATTR_COMPRESSED 0x800 +#define ATTR_OFFLINE 0x1000 +#define ATTR_NOT_INDEXED 0x2000 +#define ATTR_ENCRYPTED 0x4000 +#define ATTR_DIRECTORY 0x10000000 +#define ATTR_INDEX_VIEW 0x20000000 + +#define FLAG_COMPRESSED 1 +#define FLAG_ENCRYPTED 0x4000 +#define FLAG_SPARSE 0x8000 + +#define BLK_SHR GRUB_DISK_SECTOR_BITS + +#define MAX_MFT (1024 >> BLK_SHR) +#define MAX_IDX (16384 >> BLK_SHR) + +#define COM_LEN 4096 +#define COM_SEC (COM_LEN >> BLK_SHR) + +#define AF_ALST 1 +#define AF_MMFT 2 +#define AF_GPOS 4 + +#define RF_COMP 1 +#define RF_CBLK 2 +#define RF_BLNK 4 + +#define valueat(buf,ofs,type) *((type*)(((char*)buf)+ofs)) + +#define u16at(buf,ofs) grub_le_to_cpu16(valueat(buf,ofs,grub_uint16_t)) +#define u32at(buf,ofs) grub_le_to_cpu32(valueat(buf,ofs,grub_uint32_t)) +#define u64at(buf,ofs) grub_le_to_cpu64(valueat(buf,ofs,grub_uint64_t)) + +#define v16at(buf,ofs) valueat(buf,ofs,grub_uint16_t) +#define v32at(buf,ofs) valueat(buf,ofs,grub_uint32_t) +#define v64at(buf,ofs) valueat(buf,ofs,grub_uint64_t) + +struct grub_ntfs_bpb +{ + grub_uint8_t jmp_boot[3]; + grub_uint8_t oem_name[8]; + grub_uint16_t bytes_per_sector; + grub_uint8_t sectors_per_cluster; + grub_uint8_t reserved_1[7]; + grub_uint8_t media; + grub_uint16_t reserved_2; + grub_uint16_t sectors_per_track; + grub_uint16_t num_heads; + grub_uint32_t num_hidden_sectors; + grub_uint32_t reserved_3[2]; + grub_uint64_t num_total_sectors; + grub_uint64_t mft_lcn; + grub_uint64_t mft_mirr_lcn; + grub_int8_t clusters_per_mft; + grub_int8_t reserved_4[3]; + grub_int8_t clusters_per_index; + grub_int8_t reserved_5[3]; + grub_uint64_t num_serial; + grub_uint32_t checksum; +} __attribute__ ((packed)); + +#define grub_ntfs_file grub_fshelp_node + +struct grub_ntfs_attr +{ + int flags; + char *emft_buf, *edat_buf; + char *attr_cur, *attr_nxt, *attr_end; + grub_uint32_t save_pos; + char *sbuf; + struct grub_ntfs_file *mft; +}; + +struct grub_fshelp_node +{ + struct grub_ntfs_data *data; + char *buf; + grub_uint32_t size; + grub_uint32_t ino; + int inode_read; + struct grub_ntfs_attr attr; +}; + +struct grub_ntfs_data +{ + struct grub_ntfs_file cmft; + struct grub_ntfs_file mmft; + grub_disk_t disk; + grub_uint32_t mft_size; + grub_uint32_t idx_size; + grub_uint32_t spc; + grub_uint32_t blocksize; + grub_uint32_t mft_start; + grub_uint64_t uuid; +}; + +struct grub_ntfs_comp +{ + grub_disk_t disk; + int comp_head, comp_tail; + grub_uint32_t comp_table[16][2]; + grub_uint32_t cbuf_ofs, cbuf_vcn, spc; + char *cbuf; +}; + +struct grub_ntfs_rlst +{ + int flags; + grub_uint32_t target_vcn, curr_vcn, next_vcn, curr_lcn; + char *cur_run; + struct grub_ntfs_attr *attr; + struct grub_ntfs_comp comp; +}; + +typedef grub_err_t (*ntfscomp_func_t) (struct grub_ntfs_attr * at, char *dest, + grub_uint32_t ofs, grub_uint32_t len, + struct grub_ntfs_rlst * ctx, + grub_uint32_t vcn); + +extern ntfscomp_func_t EXPORT_VAR (grub_ntfscomp_func); + +grub_err_t EXPORT_FUNC(grub_ntfs_read_run_list) (struct grub_ntfs_rlst *ctx); + +#endif /* ! GRUB_NTFS_H */ diff --git a/include/grub/parser.h b/include/grub/parser.h new file mode 100644 index 0000000..1a7f0a3 --- /dev/null +++ b/include/grub/parser.h @@ -0,0 +1,67 @@ +/* parser.h - prototypes for the command line parser. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PARSER_HEADER +#define GRUB_PARSER_HEADER 1 + +#include +#include + +/* All the states for the command line. */ +typedef enum + { + GRUB_PARSER_STATE_TEXT = 1, + GRUB_PARSER_STATE_ESC, + GRUB_PARSER_STATE_QUOTE, + GRUB_PARSER_STATE_DQUOTE, + GRUB_PARSER_STATE_VAR, + GRUB_PARSER_STATE_VARNAME, + GRUB_PARSER_STATE_VARNAME2, + GRUB_PARSER_STATE_QVAR, + GRUB_PARSER_STATE_QVARNAME, + GRUB_PARSER_STATE_QVARNAME2 + } grub_parser_state_t; + +/* A single state transition. */ +struct grub_parser_state_transition +{ + /* The state that is looked up. */ + grub_parser_state_t from_state; + + /* The next state, determined by FROM_STATE and INPUT. */ + grub_parser_state_t to_state; + + /* The input that will determine the next state from FROM_STATE. */ + char input; + + /* If set to 1, the input is valid and should be used. */ + int keep_value; +}; + +/* Determines the state following STATE, determined by C. */ +grub_parser_state_t +EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state, + char c, char *result); + +grub_err_t +EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline, + grub_err_t (*getline) (char **), + int *argc, char ***argv); + +#endif /* ! GRUB_PARSER_HEADER */ diff --git a/include/grub/partition.h b/include/grub/partition.h new file mode 100644 index 0000000..6e74cd5 --- /dev/null +++ b/include/grub/partition.h @@ -0,0 +1,113 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PART_HEADER +#define GRUB_PART_HEADER 1 + +#include + +struct grub_disk; + +typedef struct grub_partition *grub_partition_t; + +/* Partition map type. */ +struct grub_partition_map +{ + /* The name of the partition map type. */ + const char *name; + + /* Call HOOK with each partition, until HOOK returns non-zero. */ + grub_err_t (*iterate) (struct grub_disk *disk, + int (*hook) (struct grub_disk *disk, + const grub_partition_t partition)); + + /* Return the partition named STR on the disk DISK. */ + grub_partition_t (*probe) (struct grub_disk *disk, + const char *str); + + /* Return the name of the partition PARTITION. */ + char *(*get_name) (const grub_partition_t partition); + + /* The next partition map type. */ + struct grub_partition_map *next; +}; +typedef struct grub_partition_map *grub_partition_map_t; + +/* Partition description. */ +struct grub_partition +{ + /* The start sector. */ + grub_disk_addr_t start; + + /* The length in sector units. */ + grub_uint64_t len; + + /* The offset of the partition table. */ + grub_disk_addr_t offset; + + /* The index of this partition in the partition table. */ + int index; + + /* Partition map type specific data. */ + void *data; + + /* The type partition map. */ + grub_partition_map_t partmap; +}; + +grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk, + const char *str); +int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, + int (*hook) (struct grub_disk *disk, + const grub_partition_t partition)); +char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); + +int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap)); + +void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); + +void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); + +#ifdef GRUB_UTIL +void grub_pc_partition_map_init (void); +void grub_pc_partition_map_fini (void); +void grub_amiga_partition_map_init (void); +void grub_amiga_partition_map_fini (void); +void grub_apple_partition_map_init (void); +void grub_apple_partition_map_fini (void); +void grub_sun_partition_map_init (void); +void grub_sun_partition_map_fini (void); +void grub_gpt_partition_map_init (void); +void grub_gpt_partition_map_fini (void); +void grub_apple_partition_map_init (void); +void grub_apple_partition_map_fini (void); +#endif + +static inline grub_disk_addr_t +grub_partition_get_start (const grub_partition_t p) +{ + return p->start; +} + +static inline grub_uint64_t +grub_partition_get_len (const grub_partition_t p) +{ + return p->len; +} + +#endif /* ! GRUB_PART_HEADER */ diff --git a/include/grub/pc_partition.h b/include/grub/pc_partition.h new file mode 100644 index 0000000..6a815c3 --- /dev/null +++ b/include/grub/pc_partition.h @@ -0,0 +1,209 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PC_PARTITION_HEADER +#define GRUB_PC_PARTITION_HEADER 1 + +#include +#include +#include + +/* The signature. */ +#define GRUB_PC_PARTITION_SIGNATURE 0xaa55 + +/* This is not a flag actually, but used as if it were a flag. */ +#define GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG 0x10 + +/* DOS partition types. */ +#define GRUB_PC_PARTITION_TYPE_NONE 0 +#define GRUB_PC_PARTITION_TYPE_FAT12 1 +#define GRUB_PC_PARTITION_TYPE_FAT16_LT32M 4 +#define GRUB_PC_PARTITION_TYPE_EXTENDED 5 +#define GRUB_PC_PARTITION_TYPE_FAT16_GT32M 6 +#define GRUB_PC_PARTITION_TYPE_FAT32 0xb +#define GRUB_PC_PARTITION_TYPE_FAT32_LBA 0xc +#define GRUB_PC_PARTITION_TYPE_FAT16_LBA 0xe +#define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED 0xf +#define GRUB_PC_PARTITION_TYPE_EZD 0x55 +#define GRUB_PC_PARTITION_TYPE_MINIX 0x80 +#define GRUB_PC_PARTITION_TYPE_LINUX_MINIX 0x81 +#define GRUB_PC_PARTITION_TYPE_EXT2FS 0x83 +#define GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED 0x85 +#define GRUB_PC_PARTITION_TYPE_VSTAFS 0x9e +#define GRUB_PC_PARTITION_TYPE_FREEBSD 0xa5 +#define GRUB_PC_PARTITION_TYPE_OPENBSD 0xa6 +#define GRUB_PC_PARTITION_TYPE_NETBSD 0xa9 +#define GRUB_PC_PARTITION_TYPE_GPT_DISK 0xee +#define GRUB_PC_PARTITION_TYPE_LINUX_RAID 0xfd + +/* Constants for BSD disk label. */ +#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1 +#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557 +#define GRUB_PC_PARTITION_BSD_MAX_ENTRIES 8 + +/* BSD partition types. */ +#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0 +#define GRUB_PC_PARTITION_BSD_TYPE_SWAP 1 +#define GRUB_PC_PARTITION_BSD_TYPE_V6 2 +#define GRUB_PC_PARTITION_BSD_TYPE_V7 3 +#define GRUB_PC_PARTITION_BSD_TYPE_SYSV 4 +#define GRUB_PC_PARTITION_BSD_TYPE_V71K 5 +#define GRUB_PC_PARTITION_BSD_TYPE_V8 6 +#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS 7 +#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS 8 +#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS 9 +#define GRUB_PC_PARTITION_BSD_TYPE_OTHER 10 +#define GRUB_PC_PARTITION_BSD_TYPE_HPFS 11 +#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660 12 +#define GRUB_PC_PARTITION_BSD_TYPE_BOOT 13 + +/* FreeBSD-specific types. */ +#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM 14 +#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID 15 +#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 21 + +/* NetBSD-specific types. */ +#define GRUB_PC_PARTITION_NETBSD_TYPE_ADOS 14 +#define GRUB_PC_PARTITION_NETBSD_TYPE_HFS 15 +#define GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE 16 +#define GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS 17 +#define GRUB_PC_PARTITION_NETBSD_TYPE_NTFS 18 +#define GRUB_PC_PARTITION_NETBSD_TYPE_RAID 19 +#define GRUB_PC_PARTITION_NETBSD_TYPE_CCD 20 +#define GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 21 +#define GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS 22 + +/* OpenBSD-specific types. */ +#define GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS 14 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_HFS 15 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS 17 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 + +/* The BSD partition entry. */ +struct grub_pc_partition_bsd_entry +{ + grub_uint32_t size; + grub_uint32_t offset; + grub_uint32_t fragment_size; + grub_uint8_t fs_type; + grub_uint8_t fs_fragments; + grub_uint16_t fs_cylinders; +} __attribute__ ((packed)); + +/* The BSD disk label. Only define members useful for GRUB. */ +struct grub_pc_partition_disk_label +{ + grub_uint32_t magic; + grub_uint8_t padding[128]; + grub_uint32_t magic2; + grub_uint16_t checksum; + grub_uint16_t num_partitions; + grub_uint32_t boot_size; + grub_uint32_t superblock_size; + struct grub_pc_partition_bsd_entry entries[GRUB_PC_PARTITION_BSD_MAX_ENTRIES]; +} __attribute__ ((packed)); + +/* The partition entry. */ +struct grub_pc_partition_entry +{ + /* If active, 0x80, otherwise, 0x00. */ + grub_uint8_t flag; + + /* The head of the start. */ + grub_uint8_t start_head; + + /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C + is the cylinder of the start. Note that S is counted from one. */ + grub_uint8_t start_sector; + + /* (C & 0xFF) where C is the cylinder of the start. */ + grub_uint8_t start_cylinder; + + /* The partition type. */ + grub_uint8_t type; + + /* The end versions of start_head, start_sector and start_cylinder, + respectively. */ + grub_uint8_t end_head; + grub_uint8_t end_sector; + grub_uint8_t end_cylinder; + + /* The start sector. Note that this is counted from zero. */ + grub_uint32_t start; + + /* The length in sector units. */ + grub_uint32_t length; +} __attribute__ ((packed)); + +/* The structure of MBR. */ +struct grub_pc_partition_mbr +{ + /* The code area (actually, including BPB). */ + grub_uint8_t code[446]; + + /* Four partition entries. */ + struct grub_pc_partition_entry entries[4]; + + /* The signature 0xaa55. */ + grub_uint16_t signature; +} __attribute__ ((packed)); + + +struct grub_pc_partition +{ + /* The DOS partition number. */ + int dos_part; + + /* The BSD partition number (a == 0). */ + int bsd_part; + + /* The DOS partition type. */ + int dos_type; + + /* The BSD partition type. */ + int bsd_type; + + /* The offset of the extended partition. */ + unsigned long ext_offset; +}; + +static inline int +grub_pc_partition_is_empty (int type) +{ + return (type == GRUB_PC_PARTITION_TYPE_NONE); +} + +static inline int +grub_pc_partition_is_extended (int type) +{ + return (type == GRUB_PC_PARTITION_TYPE_EXTENDED + || type == GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED + || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED); +} + +static inline int +grub_pc_partition_is_bsd (int type) +{ + return (type == GRUB_PC_PARTITION_TYPE_FREEBSD + || type == GRUB_PC_PARTITION_TYPE_OPENBSD + || type == GRUB_PC_PARTITION_TYPE_NETBSD); +} + +#endif /* ! GRUB_PC_PARTITION_HEADER */ diff --git a/include/grub/pci.h b/include/grub/pci.h new file mode 100644 index 0000000..aceee49 --- /dev/null +++ b/include/grub/pci.h @@ -0,0 +1,50 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PCI_H +#define GRUB_PCI_H 1 + +#include +#include + +#define GRUB_PCI_ADDR_SPACE_MASK 0x01 +#define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 +#define GRUB_PCI_ADDR_SPACE_IO 0x01 + +#define GRUB_PCI_ADDR_MEM_TYPE_MASK 0x06 +#define GRUB_PCI_ADDR_MEM_TYPE_32 0x00 /* 32 bit address */ +#define GRUB_PCI_ADDR_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define GRUB_PCI_ADDR_MEM_TYPE_64 0x04 /* 64 bit address */ +#define GRUB_PCI_ADDR_MEM_PREFETCH 0x08 /* prefetchable */ + +#define GRUB_PCI_ADDR_MEM_MASK ~0xf +#define GRUB_PCI_ADDR_IO_MASK ~0x03 + +typedef grub_uint32_t grub_pci_id_t; +typedef int (*grub_pci_iteratefunc_t) (int bus, int device, int func, + grub_pci_id_t pciid); +typedef grub_uint32_t grub_pci_address_t; + +grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (int bus, int device, + int function, int reg); + +void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); + +#include + +#endif /* GRUB_PCI_H */ diff --git a/include/grub/powerpc/ieee1275/biosdisk.h b/include/grub/powerpc/ieee1275/biosdisk.h new file mode 100644 index 0000000..30584d6 --- /dev/null +++ b/include/grub/powerpc/ieee1275/biosdisk.h @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BIOSDISK_MACHINE_HEADER +#define GRUB_BIOSDISK_MACHINE_HEADER 1 + +#define GRUB_BIOSDISK_FLAG_LBA 1 + +struct grub_biosdisk_data +{ + int drive; + unsigned long cylinders; + unsigned long heads; + unsigned long sectors; + unsigned long flags; +}; + +int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap); +int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, + int soff, int nsec, int segment); +int grub_biosdisk_check_int13_extensions (int drive); +int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp); +int grub_biosdisk_get_diskinfo_standard (int drive, + unsigned long *cylinders, + unsigned long *heads, + unsigned long *sectors); +int grub_biosdisk_get_num_floppies (void); + +void grub_biosdisk_init (void); + +#endif /* ! GRUB_BIOSDISK_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/console.h b/include/grub/powerpc/ieee1275/console.h new file mode 100644 index 0000000..ed2b720 --- /dev/null +++ b/include/grub/powerpc/ieee1275/console.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CONSOLE_MACHINE_HEADER +#define GRUB_CONSOLE_MACHINE_HEADER 1 + +/* Initialize the console system. */ +void grub_console_init (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h new file mode 100644 index 0000000..7e93055 --- /dev/null +++ b/include/grub/powerpc/ieee1275/ieee1275.h @@ -0,0 +1,27 @@ +/* ieee1275.h - Access the Open Firmware client interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_IEEE1275_MACHINE_HEADER +#define GRUB_IEEE1275_MACHINE_HEADER 1 + +#include + +typedef grub_uint32_t grub_ieee1275_cell_t; + +#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h new file mode 100644 index 0000000..917e154 --- /dev/null +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE + +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/loader.h b/include/grub/powerpc/ieee1275/loader.h new file mode 100644 index 0000000..606bfcd --- /dev/null +++ b/include/grub/powerpc/ieee1275/loader.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +/* The symbol shared between the normal mode and rescue mode + loader. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +void grub_linux_init (void); +void grub_linux_fini (void); +void grub_linux_normal_init (void); +void grub_linux_normal_fini (void); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/machine.h b/include/grub/powerpc/ieee1275/machine.h new file mode 100644 index 0000000..66da1d9 --- /dev/null +++ b/include/grub/powerpc/ieee1275/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_IEEE1275 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/powerpc/ieee1275/memory.h b/include/grub/powerpc/ieee1275/memory.h new file mode 100644 index 0000000..23e282f --- /dev/null +++ b/include/grub/powerpc/ieee1275/memory.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + +#endif diff --git a/include/grub/powerpc/ieee1275/time.h b/include/grub/powerpc/ieee1275/time.h new file mode 100644 index 0000000..3f8ad26 --- /dev/null +++ b/include/grub/powerpc/ieee1275/time.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 1000 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/powerpc/ieee1275/util/biosdisk.h b/include/grub/powerpc/ieee1275/util/biosdisk.h new file mode 100644 index 0000000..f4262a0 --- /dev/null +++ b/include/grub/powerpc/ieee1275/util/biosdisk.h @@ -0,0 +1,27 @@ +/* biosdisk.h - emulate biosdisk */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER +#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 + +void grub_util_biosdisk_init (const char *dev_map); +void grub_util_biosdisk_fini (void); +char *grub_util_biosdisk_get_grub_dev (const char *os_dev); + +#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h new file mode 100644 index 0000000..b468733 --- /dev/null +++ b/include/grub/powerpc/kernel.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#define GRUB_MOD_ALIGN 0x1000 + +/* Minimal gap between _end and the start of the modules. It's a hack + for PowerMac to prevent "CLAIM failed" error. The real fix is to + rewrite grub-mkimage to generate valid ELF files. */ +#define GRUB_MOD_GAP 0x8000 + +#define GRUB_KERNEL_CPU_PREFIX 0x4 +#define GRUB_KERNEL_CPU_DATA_END 0x44 + +#endif diff --git a/include/grub/powerpc/libgcc.h b/include/grub/powerpc/libgcc.h new file mode 100644 index 0000000..acdd146 --- /dev/null +++ b/include/grub/powerpc/libgcc.h @@ -0,0 +1,23 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (memset) (void); +void EXPORT_FUNC (__ashldi3) (void); +void EXPORT_FUNC (__lshrdi3) (void); +void EXPORT_FUNC (__trampoline_setup) (void); +void EXPORT_FUNC (__ucmpdi2) (void); diff --git a/include/grub/powerpc/setjmp.h b/include/grub/powerpc/setjmp.h new file mode 100644 index 0000000..441e538 --- /dev/null +++ b/include/grub/powerpc/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long grub_jmp_buf[20]; + +int grub_setjmp (grub_jmp_buf env); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/powerpc/time.h b/include/grub/powerpc/time.h new file mode 100644 index 0000000..5db7ff4 --- /dev/null +++ b/include/grub/powerpc/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: not implemented */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/powerpc/types.h b/include/grub/powerpc/types.h new file mode 100644 index 0000000..a098ae6 --- /dev/null +++ b/include/grub/powerpc/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 4 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 4 + +/* powerpc is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN 1 + + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/raid.h b/include/grub/raid.h new file mode 100644 index 0000000..a36be6d --- /dev/null +++ b/include/grub/raid.h @@ -0,0 +1,86 @@ +/* raid.h - On disk structures for RAID. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_RAID_H +#define GRUB_RAID_H 1 + +#include + +#define GRUB_RAID_MAX_DEVICES 32 + +#define GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC 0 +#define GRUB_RAID_LAYOUT_RIGHT_ASYMMETRIC 1 +#define GRUB_RAID_LAYOUT_LEFT_SYMMETRIC 2 +#define GRUB_RAID_LAYOUT_RIGHT_SYMMETRIC 3 + +#define GRUB_RAID_LAYOUT_RIGHT_MASK 1 +#define GRUB_RAID_LAYOUT_SYMMETRIC_MASK 2 + +struct grub_raid_array +{ + int number; /* The device number, taken from md_minor so we + are consistent with the device name in + Linux. */ + int level; /* RAID levels, only 0, 1 or 5 at the moment. */ + int layout; /* Layout for RAID 5/6. */ + unsigned int total_devs; /* Total number of devices in the array. */ + grub_size_t chunk_size; /* The size of a chunk, in 512 byte sectors. */ + grub_uint64_t disk_size; /* Size of an individual disk, in 512 byte + sectors. */ + int index; /* Index of current device. */ + int uuid_len; /* The length of uuid. */ + char *uuid; /* The UUID of the device. */ + + /* The following field is setup by the caller. */ + char *name; /* That will be "md". */ + unsigned int nr_devs; /* The number of devices we've found so far. */ + grub_disk_t device[GRUB_RAID_MAX_DEVICES]; /* Array of total_devs devices. */ + struct grub_raid_array *next; +}; + +struct grub_raid +{ + const char *name; + + grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array); + + struct grub_raid *next; +}; +typedef struct grub_raid *grub_raid_t; + +void grub_raid_register (grub_raid_t raid); +void grub_raid_unregister (grub_raid_t raid); + +void grub_raid_rescan (void); +void grub_raid_block_xor (char *buf1, char *buf2, int size); + +typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array, + int disknr, char *buf, + grub_disk_addr_t sector, + int size); + +typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_raid_array *array, + int disknr, int p, char *buf, + grub_disk_addr_t sector, + int size); + +extern grub_raid5_recover_func_t grub_raid5_recover_func; +extern grub_raid6_recover_func_t grub_raid6_recover_func; + +#endif /* ! GRUB_RAID_H */ diff --git a/include/grub/rescue.h b/include/grub/rescue.h new file mode 100644 index 0000000..4d8d167 --- /dev/null +++ b/include/grub/rescue.h @@ -0,0 +1,36 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_RESCUE_HEADER +#define GRUB_RESCUE_HEADER 1 + +#include + +/* Enter rescue mode. */ +void grub_enter_rescue_mode (void); + +/* Register a rescue mode command. */ +void EXPORT_FUNC(grub_rescue_register_command) (const char *name, + void (*func) (int argc, + char *argv[]), + const char *message); + +/* Unregister a rescue mode command. */ +void EXPORT_FUNC(grub_rescue_unregister_command) (const char *name); + +#endif /* ! GRUB_RESCUE_HEADER */ diff --git a/include/grub/script.h b/include/grub/script.h new file mode 100644 index 0000000..4d18b92 --- /dev/null +++ b/include/grub/script.h @@ -0,0 +1,287 @@ +/* script.h */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SCRIPT_HEADER +#define GRUB_SCRIPT_HEADER 1 + +#include +#include +#include + +struct grub_script_mem; + +/* The generic header for each scripting command or structure. */ +struct grub_script_cmd +{ + /* This function is called to execute the command. */ + grub_err_t (*exec) (struct grub_script_cmd *cmd); + + /* The next command. This can be used by the parent to form a chain + of commands. */ + struct grub_script_cmd *next; +}; + +struct grub_script +{ + struct grub_script_mem *mem; + struct grub_script_cmd *cmd; +}; + +typedef enum +{ + GRUB_SCRIPT_ARG_TYPE_STR, + GRUB_SCRIPT_ARG_TYPE_VAR +} grub_script_arg_type_t; + +/* A part of an argument. */ +struct grub_script_arg +{ + grub_script_arg_type_t type; + + char *str; + + /* Next argument part. */ + struct grub_script_arg *next; +}; + +/* A complete argument. It consists of a list of one or more `struct + grub_script_arg's. */ +struct grub_script_arglist +{ + struct grub_script_arglist *next; + struct grub_script_arg *arg; + /* Only stored in the first link. */ + int argcount; +}; + +/* A single command line. */ +struct grub_script_cmdline +{ + struct grub_script_cmd cmd; + + /* The arguments for this command. */ + struct grub_script_arglist *arglist; + + /* The command name of this command. XXX: Perhaps an argument + should be used for this so we can use variables as command + name. */ + char *cmdname; +}; + +/* A block of commands, this can be used to group commands. */ +struct grub_script_cmdblock +{ + struct grub_script_cmd cmd; + + /* A chain of commands. */ + struct grub_script_cmd *cmdlist; +}; + +/* An if statement. */ +struct grub_script_cmdif +{ + struct grub_script_cmd cmd; + + /* The command used to check if the 'if' is true or false. */ + struct grub_script_cmd *exec_to_evaluate; + + /* The code executed in case the result of 'if' was true. */ + struct grub_script_cmd *exec_on_true; + + /* The code executed in case the result of 'if' was false. */ + struct grub_script_cmd *exec_on_false; +}; + +/* A menu entry generate statement. */ +struct grub_script_cmd_menuentry +{ + struct grub_script_cmd cmd; + + /* The arguments for this menu entry. */ + struct grub_script_arglist *arglist; + + /* The sourcecode the entry will be generated from. */ + const char *sourcecode; + + /* Options. XXX: Not used yet. */ + int options; +}; + +/* State of the lexer as passed to the lexer. */ +struct grub_lexer_param +{ + /* Set to 0 when the lexer is done. */ + int done; + + /* State of the state machine. */ + grub_parser_state_t state; + + /* Function used by the lexer to get a new line when more input is + expected, but not available. */ + grub_err_t (*getline) (char **); + + /* A reference counter. If this is >0 it means that the parser + expects more tokens and `getline' should be called to fetch more. + Otherwise the lexer can stop processing if the current buffer is + depleted. */ + int refs; + + /* The character stream that has to be parsed. */ + char *script; + char *newscript; /* XXX */ + + /* While walking through the databuffer, `record' the characters to + this other buffer. It can be used to edit the menu entry at a + later moment. */ + + /* If true, recording is enabled. */ + int record; + + /* Points to the recording. */ + char *recording; + + /* index in the RECORDING. */ + int recordpos; + + /* Size of RECORDING. */ + int recordlen; +}; + +/* State of the parser as passes to the parser. */ +struct grub_parser_param +{ + /* Keep track of the memory allocated for this specific + function. */ + struct grub_script_mem *func_mem; + + /* When set to 0, no errors have occured during parsing. */ + int err; + + /* The memory that was used while parsing and scanning. */ + struct grub_script_mem *memused; + + /* The result of the parser. */ + struct grub_script_cmd *parsed; + + struct grub_lexer_param *lexerstate; +}; + +struct grub_script_arglist * +grub_script_create_arglist (struct grub_parser_param *state); + +struct grub_script_arglist * +grub_script_add_arglist (struct grub_parser_param *state, + struct grub_script_arglist *list, + struct grub_script_arg *arg); +struct grub_script_cmd * +grub_script_create_cmdline (struct grub_parser_param *state, + char *cmdname, + struct grub_script_arglist *arglist); +struct grub_script_cmd * +grub_script_create_cmdblock (struct grub_parser_param *state); + +struct grub_script_cmd * +grub_script_create_cmdif (struct grub_parser_param *state, + struct grub_script_cmd *exec_to_evaluate, + struct grub_script_cmd *exec_on_true, + struct grub_script_cmd *exec_on_false); + +struct grub_script_cmd * +grub_script_create_cmdmenu (struct grub_parser_param *state, + struct grub_script_arglist *arglist, + char *sourcecode, + int options); + +struct grub_script_cmd * +grub_script_add_cmd (struct grub_parser_param *state, + struct grub_script_cmdblock *cmdblock, + struct grub_script_cmd *cmd); +struct grub_script_arg * +grub_script_arg_add (struct grub_parser_param *state, + struct grub_script_arg *arg, + grub_script_arg_type_t type, char *str); + +struct grub_script *grub_script_parse (char *script, + grub_err_t (*getline) (char **)); +void grub_script_free (struct grub_script *script); +struct grub_script *grub_script_create (struct grub_script_cmd *cmd, + struct grub_script_mem *mem); + +struct grub_lexer_param *grub_script_lexer_init (char *s, + grub_err_t (*getline) (char **)); +void grub_script_lexer_ref (struct grub_lexer_param *); +void grub_script_lexer_deref (struct grub_lexer_param *); +void grub_script_lexer_record_start (struct grub_lexer_param *); +char *grub_script_lexer_record_stop (struct grub_lexer_param *); + +/* Functions to track allocated memory. */ +struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state); +struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param *state, + struct grub_script_mem *restore); +void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size); + +/* Functions used by bison. */ +union YYSTYPE; +int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *); +int grub_script_yyparse (struct grub_parser_param *); +void grub_script_yyerror (struct grub_parser_param *, char const *); + +/* Commands to execute, don't use these directly. */ +grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd); + +/* Execute any GRUB pre-parsed command or script. */ +grub_err_t grub_script_execute (struct grub_script *script); + +/* This variable points to the parsed command. This is used to + communicate with the bison code. */ +extern struct grub_script_cmd *grub_script_parsed; + + + +/* The function description. */ +struct grub_script_function +{ + /* The name. */ + char *name; + + /* The script function. */ + struct grub_script *func; + + /* The flags. */ + unsigned flags; + + /* The next element. */ + struct grub_script_function *next; + + int references; +}; +typedef struct grub_script_function *grub_script_function_t; + +grub_script_function_t grub_script_function_create (char *functionname, + struct grub_script *cmd); +void grub_script_function_remove (const char *name); +grub_script_function_t grub_script_function_find (char *functionname); +int grub_script_function_iterate (int (*iterate) (grub_script_function_t)); +int grub_script_function_call (grub_script_function_t func, + int argc, char **args); + +#endif /* ! GRUB_SCRIPT_HEADER */ diff --git a/include/grub/scsi.h b/include/grub/scsi.h new file mode 100644 index 0000000..fbe4582 --- /dev/null +++ b/include/grub/scsi.h @@ -0,0 +1,88 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SCSI_H +#define GRUB_SCSI_H 1 + +typedef struct grub_scsi_dev *grub_scsi_dev_t; + +void grub_scsi_dev_register (grub_scsi_dev_t dev); +void grub_scsi_dev_unregister (grub_scsi_dev_t dev); + +struct grub_scsi; + +struct grub_scsi_dev +{ + /* The device name. */ + const char *name; + + /* Call HOOK with each device name, until HOOK returns non-zero. */ + int (*iterate) (int (*hook) (const char *name, int luns)); + + /* Open the device named NAME, and set up SCSI. */ + grub_err_t (*open) (const char *name, struct grub_scsi *scsi); + + /* Close the scsi device SCSI. */ + void (*close) (struct grub_scsi *scsi); + + /* Read SIZE bytes from the device SCSI into BUF after sending the + command CMD of size CMDSIZE. */ + grub_err_t (*read) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf); + + /* Write SIZE bytes from BUF to the device SCSI after sending the + command CMD of size CMDSIZE. */ + grub_err_t (*write) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + grub_size_t size, char *buf); + + /* The next scsi device. */ + struct grub_scsi_dev *next; +}; + +struct grub_scsi +{ + /* The scsi device name. */ + char *name; + + /* The underlying scsi device. */ + grub_scsi_dev_t dev; + + /* Type of SCSI device. XXX: Make enum. */ + grub_uint8_t devtype; + + /* Number of LUNs. */ + int luns; + + /* LUN for this `struct grub_scsi'. */ + int lun; + + /* Set to 0 when not removable, 1 when removable. */ + int removable; + + /* Size of the device in blocks. */ + int size; + + /* Size of one block. */ + int blocksize; + + /* Device-specific data. */ + void *data; +}; +typedef struct grub_scsi *grub_scsi_t; + +#endif /* GRUB_SCSI_H */ diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h new file mode 100644 index 0000000..40f237a --- /dev/null +++ b/include/grub/scsicmd.h @@ -0,0 +1,122 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SCSICMD_H +#define GRUB_SCSICMD_H 1 + +#include + +#define GRUB_SCSI_DEVTYPE_MASK 31 +#define GRUB_SCSI_REMOVABLE_BIT 7 +#define GRUB_SCSI_LUN_SHIFT 5 + +struct grub_scsi_inquiry +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint16_t reserved; + grub_uint16_t alloc_length; + grub_uint8_t reserved2; + grub_uint8_t pad[5]; +} __attribute__((packed)); + +struct grub_scsi_inquiry_data +{ + grub_uint8_t devtype; + grub_uint8_t rmb; + grub_uint16_t reserved; + grub_uint8_t length; + grub_uint8_t reserved2[3]; + char vendor[8]; + char prodid[16]; + char prodrev[4]; +} __attribute__((packed)); + +struct grub_scsi_read_capacity +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint8_t reserved[8]; + grub_uint8_t pad[2]; +} __attribute__((packed)); + +struct grub_scsi_read_capacity_data +{ + grub_uint32_t size; + grub_uint32_t blocksize; +} __attribute__((packed)); + +struct grub_scsi_read10 +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint32_t lba; + grub_uint8_t reserved; + grub_uint16_t size; + grub_uint8_t reserved2; + grub_uint16_t pad; +} __attribute__((packed)); + +struct grub_scsi_read12 +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint32_t lba; + grub_uint32_t size; + grub_uint8_t reserved; + grub_uint8_t control; +} __attribute__((packed)); + +struct grub_scsi_write10 +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint32_t lba; + grub_uint8_t reserved; + grub_uint16_t size; + grub_uint8_t reserved2; + grub_uint16_t pad; +} __attribute__((packed)); + +struct grub_scsi_write12 +{ + grub_uint8_t opcode; + grub_uint8_t lun; + grub_uint32_t lba; + grub_uint32_t size; + grub_uint8_t reserved; + grub_uint8_t control; +} __attribute__((packed)); + +typedef enum + { + grub_scsi_cmd_inquiry = 0x12, + grub_scsi_cmd_read_capacity = 0x25, + grub_scsi_cmd_read10 = 0x28, + grub_scsi_cmd_write10 = 0x2a, + grub_scsi_cmd_read12 = 0xa8, + grub_scsi_cmd_write12 = 0xaa + } grub_scsi_cmd_t; + +typedef enum + { + grub_scsi_devtype_direct = 0x00, + grub_scsi_devtype_cdrom = 0x05 + } grub_scsi_devtype_t; + +#endif /* GRUB_SCSICMD_H */ diff --git a/include/grub/setjmp.h b/include/grub/setjmp.h new file mode 100644 index 0000000..70147a7 --- /dev/null +++ b/include/grub/setjmp.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_HEADER +#define GRUB_SETJMP_HEADER 1 + +#if defined(GRUB_UTIL) && !defined(GRUBOF) +#include +typedef jmp_buf grub_jmp_buf; +#define grub_setjmp setjmp +#define grub_longjmp longjmp +#else +/* This must define grub_jmp_buf, and declare grub_setjmp and + grub_longjmp. */ +# include +#endif + +#endif /* ! GRUB_SETJMP_HEADER */ diff --git a/include/grub/sparc64/ieee1275/console.h b/include/grub/sparc64/ieee1275/console.h new file mode 100644 index 0000000..ed2b720 --- /dev/null +++ b/include/grub/sparc64/ieee1275/console.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CONSOLE_MACHINE_HEADER +#define GRUB_CONSOLE_MACHINE_HEADER 1 + +/* Initialize the console system. */ +void grub_console_init (void); + +/* Finish the console system. */ +void grub_console_fini (void); + +#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h new file mode 100644 index 0000000..1ef95f9 --- /dev/null +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -0,0 +1,27 @@ +/* ieee1275.h - Access the Open Firmware client interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_IEEE1275_MACHINE_HEADER +#define GRUB_IEEE1275_MACHINE_HEADER 1 + +#include + +typedef grub_uint64_t grub_ieee1275_cell_t; + +#endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h new file mode 100644 index 0000000..0b6bce2 --- /dev/null +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +/* Where grub-mkimage places the core modules in memory. */ +#define GRUB_IEEE1275_MODULE_BASE 0x00300000 + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/machine.h b/include/grub/sparc64/ieee1275/machine.h new file mode 100644 index 0000000..66da1d9 --- /dev/null +++ b/include/grub/sparc64/ieee1275/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_IEEE1275 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/time.h b/include/grub/sparc64/ieee1275/time.h new file mode 100644 index 0000000..3f8ad26 --- /dev/null +++ b/include/grub/sparc64/ieee1275/time.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 1000 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/sparc64/libgcc.h b/include/grub/sparc64/libgcc.h new file mode 100644 index 0000000..e30c717 --- /dev/null +++ b/include/grub/sparc64/libgcc.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (memset) (void); diff --git a/include/grub/sparc64/setjmp.h b/include/grub/sparc64/setjmp.h new file mode 100644 index 0000000..12d8e01 --- /dev/null +++ b/include/grub/sparc64/setjmp.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +/* FIXME (sparc64). */ +typedef unsigned long grub_jmp_buf[20]; + +int grub_setjmp (grub_jmp_buf env); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/sparc64/time.h b/include/grub/sparc64/time.h new file mode 100644 index 0000000..5db7ff4 --- /dev/null +++ b/include/grub/sparc64/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: not implemented */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/sparc64/types.h b/include/grub/sparc64/types.h new file mode 100644 index 0000000..b9b0cf9 --- /dev/null +++ b/include/grub/sparc64/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* sparc64 is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN 1 + + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/symbol.h b/include/grub/symbol.h new file mode 100644 index 0000000..ef19a73 --- /dev/null +++ b/include/grub/symbol.h @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SYMBOL_HEADER +#define GRUB_SYMBOL_HEADER 1 + +#include + +/* Add an underscore to a C symbol in assembler code if needed. */ +#ifdef HAVE_ASM_USCORE +# define EXT_C(sym) _ ## sym +#else +# define EXT_C(sym) sym +#endif + +#if ! defined (__CYGWIN__) && ! defined (__MINGW32__) +#define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x): +#define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x): +#else +/* .type not supported for non-ELF targets. XXX: Check this in configure? */ +#define FUNCTION(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; .endef; EXT_C(x): +#define VARIABLE(x) .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; .endef; EXT_C(x): +#endif + +/* Mark an exported symbol. */ +#ifndef GRUB_SYMBOL_GENERATOR +# define EXPORT_FUNC(x) x +# define EXPORT_VAR(x) x +#endif /* ! GRUB_SYMBOL_GENERATOR */ + +#endif /* ! GRUB_SYMBOL_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h new file mode 100644 index 0000000..13835bb --- /dev/null +++ b/include/grub/term.h @@ -0,0 +1,253 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TERM_HEADER +#define GRUB_TERM_HEADER 1 + +/* Internal codes used by GRUB to represent terminal input. */ +#define GRUB_TERM_LEFT 2 +#define GRUB_TERM_RIGHT 6 +#define GRUB_TERM_UP 16 +#define GRUB_TERM_DOWN 14 +#define GRUB_TERM_HOME 1 +#define GRUB_TERM_END 5 +#define GRUB_TERM_DC 4 +#define GRUB_TERM_PPAGE 7 +#define GRUB_TERM_NPAGE 3 +#define GRUB_TERM_ESC '\e' +#define GRUB_TERM_TAB '\t' +#define GRUB_TERM_BACKSPACE '\b' + +#ifndef ASM_FILE + +#include +#include +#include + +/* These are used to represent the various color states we use. */ +typedef enum + { + /* The color used to display all text that does not use the + user defined colors below. */ + GRUB_TERM_COLOR_STANDARD, + /* The user defined colors for normal text. */ + GRUB_TERM_COLOR_NORMAL, + /* The user defined colors for highlighted text. */ + GRUB_TERM_COLOR_HIGHLIGHT + } +grub_term_color_state; + +/* Flags for representing the capabilities of a terminal. */ +/* Some notes about the flags: + - These flags are used by higher-level functions but not terminals + themselves. + - If a terminal is dumb, you may assume that only putchar, getkey and + checkkey are called. + - Some fancy features (setcolorstate, setcolor and setcursor) can be set + to NULL. */ + +/* Set when input characters shouldn't be echoed back. */ +#define GRUB_TERM_NO_ECHO (1 << 0) +/* Set when the editing feature should be disabled. */ +#define GRUB_TERM_NO_EDIT (1 << 1) +/* Set when the terminal cannot do fancy things. */ +#define GRUB_TERM_DUMB (1 << 2) +/* Set when the terminal needs to be initialized. */ +#define GRUB_TERM_NEED_INIT (1 << 16) + + +/* Unicode characters for fancy graphics. */ +#define GRUB_TERM_DISP_LEFT 0x2190 +#define GRUB_TERM_DISP_UP 0x2191 +#define GRUB_TERM_DISP_RIGHT 0x2192 +#define GRUB_TERM_DISP_DOWN 0x2193 +#define GRUB_TERM_DISP_HLINE 0x2501 +#define GRUB_TERM_DISP_VLINE 0x2503 +#define GRUB_TERM_DISP_UL 0x250F +#define GRUB_TERM_DISP_UR 0x2513 +#define GRUB_TERM_DISP_LL 0x2517 +#define GRUB_TERM_DISP_LR 0x251B + + +/* Menu-related geometrical constants. */ + +/* FIXME: Ugly way to get them form terminal. */ +#define GRUB_TERM_WIDTH ((grub_getwh()&0xFF00)>>8) +#define GRUB_TERM_HEIGHT (grub_getwh()&0xFF) + +/* The number of lines of "GRUB version..." at the top. */ +#define GRUB_TERM_INFO_HEIGHT 1 + +/* The number of columns/lines between messages/borders/etc. */ +#define GRUB_TERM_MARGIN 1 + +/* The number of columns of scroll information. */ +#define GRUB_TERM_SCROLL_WIDTH 1 + +/* The Y position of the top border. */ +#define GRUB_TERM_TOP_BORDER_Y (GRUB_TERM_MARGIN + GRUB_TERM_INFO_HEIGHT \ + + GRUB_TERM_MARGIN) + +/* The X position of the left border. */ +#define GRUB_TERM_LEFT_BORDER_X GRUB_TERM_MARGIN + +/* The width of the border. */ +#define GRUB_TERM_BORDER_WIDTH (GRUB_TERM_WIDTH \ + - GRUB_TERM_MARGIN * 3 \ + - GRUB_TERM_SCROLL_WIDTH) + +/* The number of lines of messages at the bottom. */ +#define GRUB_TERM_MESSAGE_HEIGHT 8 + +/* The height of the border. */ +#define GRUB_TERM_BORDER_HEIGHT (GRUB_TERM_HEIGHT \ + - GRUB_TERM_TOP_BORDER_Y \ + - GRUB_TERM_MESSAGE_HEIGHT) + +/* The number of entries shown at a time. */ +#define GRUB_TERM_NUM_ENTRIES (GRUB_TERM_BORDER_HEIGHT - 2) + +/* The Y position of the first entry. */ +#define GRUB_TERM_FIRST_ENTRY_Y (GRUB_TERM_TOP_BORDER_Y + 1) + +/* The max column number of an entry. The last "-1" is for a + continuation marker. */ +#define GRUB_TERM_ENTRY_WIDTH (GRUB_TERM_BORDER_WIDTH - 2 \ + - GRUB_TERM_MARGIN * 2 - 1) + +/* The standard X position of the cursor. */ +#define GRUB_TERM_CURSOR_X (GRUB_TERM_LEFT_BORDER_X \ + + GRUB_TERM_BORDER_WIDTH \ + - GRUB_TERM_MARGIN \ + - 1) + + +struct grub_term_input +{ + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (void); + + /* Clean up the terminal. */ + grub_err_t (*fini) (void); + + /* Check if any input character is available. */ + int (*checkkey) (void); + + /* Get a character. */ + int (*getkey) (void); + + /* The next terminal. */ + struct grub_term_input *next; +}; +typedef struct grub_term_input *grub_term_input_t; + +struct grub_term_output +{ + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (void); + + /* Clean up the terminal. */ + grub_err_t (*fini) (void); + + /* Put a character. C is encoded in Unicode. */ + void (*putchar) (grub_uint32_t c); + + /* Get the number of columns occupied by a given character C. C is + encoded in Unicode. */ + grub_ssize_t (*getcharwidth) (grub_uint32_t c); + + /* Get the screen size. The return value is ((Width << 8) | Height). */ + grub_uint16_t (*getwh) (void); + + /* Get the cursor position. The return value is ((X << 8) | Y). */ + grub_uint16_t (*getxy) (void); + + /* Go to the position (X, Y). */ + void (*gotoxy) (grub_uint8_t x, grub_uint8_t y); + + /* Clear the screen. */ + void (*cls) (void); + + /* Set the current color to be used */ + void (*setcolorstate) (grub_term_color_state state); + + /* Set the normal color and the highlight color. The format of each + color is VGA's. */ + void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color); + + /* Get the normal color and the highlight color. The format of each + color is VGA's. */ + void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color); + + /* Turn on/off the cursor. */ + void (*setcursor) (int on); + + /* Update the screen. */ + void (*refresh) (void); + + /* The feature flags defined above. */ + grub_uint32_t flags; + + /* The next terminal. */ + struct grub_term_output *next; +}; +typedef struct grub_term_output *grub_term_output_t; + +void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term); +void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term); +void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term); +void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term); +void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term)); +void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term)); + +grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term); +grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term); +grub_term_input_t EXPORT_FUNC(grub_term_get_current_input) (void); +grub_term_output_t EXPORT_FUNC(grub_term_get_current_output) (void); + +void EXPORT_FUNC(grub_putchar) (int c); +void EXPORT_FUNC(grub_putcode) (grub_uint32_t code); +grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_checkkey) (void); +grub_uint16_t EXPORT_FUNC(grub_getwh) (void); +grub_uint16_t EXPORT_FUNC(grub_getxy) (void); +void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y); +void EXPORT_FUNC(grub_cls) (void); +void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); +void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color, + grub_uint8_t highlight_color); +void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color, + grub_uint8_t *highlight_color); +int EXPORT_FUNC(grub_setcursor) (int on); +int EXPORT_FUNC(grub_getcursor) (void); +void EXPORT_FUNC(grub_refresh) (void); +void EXPORT_FUNC(grub_set_more) (int onoff); + +/* For convenience. */ +#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff) + +#endif /* ! ASM_FILE */ + +#endif /* ! GRUB_TERM_HEADER */ diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h new file mode 100644 index 0000000..1ea741e --- /dev/null +++ b/include/grub/terminfo.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TERMINFO_HEADER +#define GRUB_TERMINFO_HEADER 1 + +#include +#include + +char *grub_terminfo_get_current (void); +grub_err_t grub_terminfo_set_current (const char *); + +void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y); +void grub_terminfo_cls (void); +void grub_terminfo_reverse_video_on (void); +void grub_terminfo_reverse_video_off (void); +void grub_terminfo_cursor_on (void); +void grub_terminfo_cursor_off (void); + +#endif /* ! GRUB_TERMINFO_HEADER */ diff --git a/include/grub/time.h b/include/grub/time.h new file mode 100644 index 0000000..4dcd843 --- /dev/null +++ b/include/grub/time.h @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_TIME_HEADER +#define KERNEL_TIME_HEADER 1 + +#include +#include +#include +#include + +void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); +grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); + +grub_uint64_t grub_rtc_get_time_ms (void); + +static __inline void +grub_sleep (grub_uint32_t s) +{ + grub_millisleep (1000 * s); +} + +void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void)); + +#endif /* ! KERNEL_TIME_HEADER */ diff --git a/include/grub/tparm.h b/include/grub/tparm.h new file mode 100644 index 0000000..642a22f --- /dev/null +++ b/include/grub/tparm.h @@ -0,0 +1,26 @@ +/* tparm.h - parameter formatting of terminfo */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TPARM_HEADER +#define GRUB_TPARM_HEADER 1 + +/* Function prototypes. */ +char *grub_terminfo_tparm (const char *string, ...); + +#endif /* ! GRUB_TPARM_HEADER */ diff --git a/include/grub/types.h b/include/grub/types.h new file mode 100644 index 0000000..8d51b66 --- /dev/null +++ b/include/grub/types.h @@ -0,0 +1,208 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_HEADER +#define GRUB_TYPES_HEADER 1 + +#include +#include + +#define UNUSED __attribute__ ((unused)) + +#ifdef GRUB_UTIL +# define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P +# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG +# ifdef WORDS_BIGENDIAN +# define GRUB_CPU_WORDS_BIGENDIAN 1 +# else +# undef GRUB_CPU_WORDS_BIGENDIAN +# endif +#else /* ! GRUB_UTIL */ +# define GRUB_CPU_SIZEOF_VOID_P GRUB_TARGET_SIZEOF_VOID_P +# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG +# ifdef GRUB_TARGET_WORDS_BIGENDIAN +# define GRUB_CPU_WORDS_BIGENDIAN 1 +# else +# undef GRUB_CPU_WORDS_BIGENDIAN +# endif +#endif /* ! GRUB_UTIL */ + +#if GRUB_CPU_SIZEOF_VOID_P != GRUB_CPU_SIZEOF_LONG +# error "This architecture is not supported because sizeof(void *) != sizeof(long)" +#endif + +#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8 +# error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8" +#endif + +/* Define various wide integers. */ +typedef signed char grub_int8_t; +typedef short grub_int16_t; +typedef int grub_int32_t; +#if GRUB_CPU_SIZEOF_VOID_P == 8 +typedef long grub_int64_t; +#else +typedef long long grub_int64_t; +#endif + +typedef unsigned char grub_uint8_t; +typedef unsigned short grub_uint16_t; +typedef unsigned grub_uint32_t; +#if GRUB_CPU_SIZEOF_VOID_P == 8 +typedef unsigned long grub_uint64_t; +#else +typedef unsigned long long grub_uint64_t; +#endif + +/* Misc types. */ +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +typedef grub_uint64_t grub_target_addr_t; +typedef grub_uint64_t grub_target_off_t; +typedef grub_uint64_t grub_target_size_t; +typedef grub_int64_t grub_target_ssize_t; +#else +typedef grub_uint32_t grub_target_addr_t; +typedef grub_uint32_t grub_target_off_t; +typedef grub_uint32_t grub_target_size_t; +typedef grub_int32_t grub_target_ssize_t; +#endif + +#if GRUB_CPU_SIZEOF_VOID_P == 8 +typedef grub_uint64_t grub_addr_t; +typedef grub_uint64_t grub_size_t; +typedef grub_int64_t grub_ssize_t; +#else +typedef grub_uint32_t grub_addr_t; +typedef grub_uint32_t grub_size_t; +typedef grub_int32_t grub_ssize_t; +#endif + +#if GRUB_CPU_SIZEOF_VOID_P == 8 +# define ULONG_MAX 18446744073709551615UL +# define LONG_MAX 9223372036854775807UL +#else +# define ULONG_MAX 4294967295UL +# define LONG_MAX 2147483647UL +#endif + +/* The type for representing a file offset. */ +typedef grub_uint64_t grub_off_t; + +/* The type for representing a disk block address. */ +typedef grub_uint64_t grub_disk_addr_t; + +/* Byte-orders. */ +#define grub_swap_bytes16(x) \ +({ \ + grub_uint16_t _x = (x); \ + (grub_uint16_t) ((_x << 8) | (_x >> 8)); \ +}) + +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) +static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x) +{ + return __builtin_bswap32(x); +} + +static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) +{ + return __builtin_bswap64(x); +} +#else /* not gcc 4.3 or newer */ +#define grub_swap_bytes32(x) \ +({ \ + grub_uint32_t _x = (x); \ + (grub_uint32_t) ((_x << 24) \ + | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \ + | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \ + | (_x >> 24)); \ +}) + +#define grub_swap_bytes64(x) \ +({ \ + grub_uint64_t _x = (x); \ + (grub_uint64_t) ((_x << 56) \ + | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \ + | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \ + | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \ + | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \ + | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \ + | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \ + | (_x >> 56)); \ +}) +#endif /* not gcc 4.3 or newer */ + +#ifdef GRUB_CPU_WORDS_BIGENDIAN +# define grub_cpu_to_le16(x) grub_swap_bytes16(x) +# define grub_cpu_to_le32(x) grub_swap_bytes32(x) +# define grub_cpu_to_le64(x) grub_swap_bytes64(x) +# define grub_le_to_cpu16(x) grub_swap_bytes16(x) +# define grub_le_to_cpu32(x) grub_swap_bytes32(x) +# define grub_le_to_cpu64(x) grub_swap_bytes64(x) +# define grub_cpu_to_be16(x) ((grub_uint16_t) (x)) +# define grub_cpu_to_be32(x) ((grub_uint32_t) (x)) +# define grub_cpu_to_be64(x) ((grub_uint64_t) (x)) +# define grub_be_to_cpu16(x) ((grub_uint16_t) (x)) +# define grub_be_to_cpu32(x) ((grub_uint32_t) (x)) +# define grub_be_to_cpu64(x) ((grub_uint64_t) (x)) +# ifdef GRUB_TARGET_WORDS_BIGENDIAN +# define grub_target_to_host16(x) ((grub_uint16_t) (x)) +# define grub_target_to_host32(x) ((grub_uint32_t) (x)) +# define grub_target_to_host64(x) ((grub_uint64_t) (x)) +# define grub_host_to_target16(x) ((grub_uint16_t) (x)) +# define grub_host_to_target32(x) ((grub_uint32_t) (x)) +# define grub_host_to_target64(x) ((grub_uint64_t) (x)) +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ +# define grub_target_to_host16(x) grub_swap_bytes16(x) +# define grub_target_to_host32(x) grub_swap_bytes32(x) +# define grub_target_to_host64(x) grub_swap_bytes64(x) +# define grub_host_to_target16(x) grub_swap_bytes16(x) +# define grub_host_to_target32(x) grub_swap_bytes32(x) +# define grub_host_to_target64(x) grub_swap_bytes64(x) +# endif +#else /* ! WORDS_BIGENDIAN */ +# define grub_cpu_to_le16(x) ((grub_uint16_t) (x)) +# define grub_cpu_to_le32(x) ((grub_uint32_t) (x)) +# define grub_cpu_to_le64(x) ((grub_uint64_t) (x)) +# define grub_le_to_cpu16(x) ((grub_uint16_t) (x)) +# define grub_le_to_cpu32(x) ((grub_uint32_t) (x)) +# define grub_le_to_cpu64(x) ((grub_uint64_t) (x)) +# define grub_cpu_to_be16(x) grub_swap_bytes16(x) +# define grub_cpu_to_be32(x) grub_swap_bytes32(x) +# define grub_cpu_to_be64(x) grub_swap_bytes64(x) +# define grub_be_to_cpu16(x) grub_swap_bytes16(x) +# define grub_be_to_cpu32(x) grub_swap_bytes32(x) +# define grub_be_to_cpu64(x) grub_swap_bytes64(x) +# ifdef GRUB_TARGET_WORDS_BIGENDIAN +# define grub_target_to_host16(x) grub_swap_bytes16(x) +# define grub_target_to_host32(x) grub_swap_bytes32(x) +# define grub_target_to_host64(x) grub_swap_bytes64(x) +# define grub_host_to_target16(x) grub_swap_bytes16(x) +# define grub_host_to_target32(x) grub_swap_bytes32(x) +# define grub_host_to_target64(x) grub_swap_bytes64(x) +# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ +# define grub_target_to_host16(x) ((grub_uint16_t) (x)) +# define grub_target_to_host32(x) ((grub_uint32_t) (x)) +# define grub_target_to_host64(x) ((grub_uint64_t) (x)) +# define grub_host_to_target16(x) ((grub_uint16_t) (x)) +# define grub_host_to_target32(x) ((grub_uint32_t) (x)) +# define grub_host_to_target64(x) ((grub_uint64_t) (x)) +# endif +#endif /* ! WORDS_BIGENDIAN */ + +#endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/usb.h b/include/grub/usb.h new file mode 100644 index 0000000..9c9e58b --- /dev/null +++ b/include/grub/usb.h @@ -0,0 +1,207 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_USB_H +#define GRUB_USB_H 1 + +#include +#include + +typedef struct grub_usb_device *grub_usb_device_t; +typedef struct grub_usb_controller *grub_usb_controller_t; +typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; + +typedef enum + { + GRUB_USB_ERR_NONE, + GRUB_USB_ERR_INTERNAL, + GRUB_USB_ERR_STALL, + GRUB_USB_ERR_DATA, + GRUB_USB_ERR_NAK, + GRUB_USB_ERR_BABBLE, + GRUB_USB_ERR_TIMEOUT, + GRUB_USB_ERR_BITSTUFF + } grub_usb_err_t; + +typedef enum + { + GRUB_USB_SPEED_NONE, + GRUB_USB_SPEED_LOW, + GRUB_USB_SPEED_FULL, + GRUB_USB_SPEED_HIGH + } grub_usb_speed_t; + +/* Call HOOK with each device, until HOOK returns non-zero. */ +int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)); + +grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev); + +grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev, + grub_uint8_t type, grub_uint8_t index, + grub_size_t size, char *data); + +struct grub_usb_desc_endp * +grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr); + +grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint); + + +grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, + int configuration); + +grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, + int langid, char **string); + +void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb); + +void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb); + +int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev)); + + +grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, + grub_uint8_t request, grub_uint16_t value, + grub_uint16_t index, grub_size_t size, + char *data); + +grub_usb_err_t +grub_usb_bulk_read (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data); +grub_usb_err_t +grub_usb_bulk_write (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data); + +grub_usb_err_t +grub_usb_root_hub (grub_usb_controller_t controller); + + +/* XXX: All handled by libusb for now. */ +struct grub_usb_controller_dev +{ + /* The device name. */ + const char *name; + + int (*iterate) (int (*hook) (grub_usb_controller_t dev)); + + grub_usb_err_t (*transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer); + + int (*hubports) (grub_usb_controller_t dev); + + grub_err_t (*portstatus) (grub_usb_controller_t dev, unsigned int port, + unsigned int enable); + + grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port); + + /* The next host controller. */ + struct grub_usb_controller_dev *next; +}; + +struct grub_usb_controller +{ + /* The underlying USB Host Controller device. */ + grub_usb_controller_dev_t dev; + + /* Data used by the USB Host Controller Driver. */ + void *data; +}; + + +struct grub_usb_interface +{ + struct grub_usb_desc_if *descif; + + struct grub_usb_desc_endp *descendp; +}; + +struct grub_usb_configuration +{ + /* Configuration descriptors . */ + struct grub_usb_desc_config *descconf; + + /* Interfaces associated to this configuration. */ + struct grub_usb_interface interf[32]; +}; + +struct grub_usb_device +{ + /* The device descriptor of this device. */ + struct grub_usb_desc_device descdev; + + /* The controller the device is connected to. */ + struct grub_usb_controller controller; + + /* Device configurations (after opening the device). */ + struct grub_usb_configuration config[8]; + + /* Device address. */ + int addr; + + /* Device speed. */ + grub_usb_speed_t speed; + + /* All desciptors are read if this is set to 1. */ + int initialized; + + /* Data toggle values (used for bulk transfers only). */ + int toggle[16]; + + /* Device-specific data. */ + void *data; +}; + + + +typedef enum + { + GRUB_USB_CLASS_NOTHERE, + GRUB_USB_CLASS_AUDIO, + GRUB_USB_CLASS_COMMUNICATION, + GRUB_USB_CLASS_HID, + GRUB_USB_CLASS_XXX, + GRUB_USB_CLASS_PHYSICAL, + GRUB_USB_CLASS_IMAGE, + GRUB_USB_CLASS_PRINTER, + GRUB_USB_CLASS_MASS_STORAGE, + GRUB_USB_CLASS_HUB, + GRUB_USB_CLASS_DATA_INTERFACE, + GRUB_USB_CLASS_SMART_CARD, + GRUB_USB_CLASS_CONTENT_SECURITY, + GRUB_USB_CLASS_VIDEO + } grub_usb_classes_t; + +typedef enum + { + GRUB_USBMS_SUBCLASS_BULK = 0x06 + } grub_usbms_subclass_t; + +typedef enum + { + GRUB_USBMS_PROTOCOL_BULK = 0x50 + } grub_usbms_protocol_t; + +static inline struct grub_usb_desc_if * +grub_usb_get_config_interface (struct grub_usb_desc_config *config) +{ + struct grub_usb_desc_if *interf; + + interf = (struct grub_usb_desc_if *) (sizeof (*config) + (char *) config); + return interf; +} + +#endif /* GRUB_USB_H */ diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h new file mode 100644 index 0000000..97947dc --- /dev/null +++ b/include/grub/usbdesc.h @@ -0,0 +1,119 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_USBDESC_H +#define GRUB_USBDESC_H 1 + +#include +#include + +typedef enum { + GRUB_USB_DESCRIPTOR_DEVICE = 1, + GRUB_USB_DESCRIPTOR_CONFIG, + GRUB_USB_DESCRIPTOR_STRING, + GRUB_USB_DESCRIPTOR_INTERFACE, + GRUB_USB_DESCRIPTOR_ENDPOINT, + GRUB_USB_DESCRIPTOR_HUB = 0x29 +} grub_usb_descriptor_t; + +struct grub_usb_desc_device +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint16_t usbrel; + grub_uint8_t class; + grub_uint8_t subclass; + grub_uint8_t protocol; + grub_uint8_t maxsize0; + grub_uint16_t vendorid; + grub_uint16_t prodid; + grub_uint16_t devrel; + grub_uint8_t strvendor; + grub_uint8_t strprod; + grub_uint8_t strserial; + grub_uint8_t configcnt; +} __attribute__ ((packed)); + +struct grub_usb_desc_config +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint16_t totallen; + grub_uint8_t numif; + grub_uint8_t config; + grub_uint8_t strconfig; + grub_uint8_t attrib; + grub_uint8_t maxpower; +} __attribute__ ((packed)); + +#if 0 +struct grub_usb_desc_ifassosiation +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint8_t firstif; + grub_uint8_t ifcnt; + grub_uint8_t class; + grub_uint8_t subclass; + grub_uint8_t protocol; + grub_uint8_t function; +} __attribute__ ((packed)); +#endif + +struct grub_usb_desc_if +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint8_t ifnum; + grub_uint8_t altsetting; + grub_uint8_t endpointcnt; + grub_uint8_t class; + grub_uint8_t subclass; + grub_uint8_t protocol; + grub_uint8_t strif; +} __attribute__ ((packed)); + +struct grub_usb_desc_endp +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint8_t endp_addr; + grub_uint8_t attrib; + grub_uint16_t maxpacket; + grub_uint8_t interval; +} __attribute__ ((packed)); + +struct grub_usb_desc_str +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint16_t str[0]; +} __attribute__ ((packed)); + +struct grub_usb_usb_hubdesc +{ + grub_uint8_t length; + grub_uint8_t type; + grub_uint8_t portcnt; + grub_uint16_t characteristics; + grub_uint8_t pwdgood; + grub_uint8_t current; + /* Removable and power control bits follow. */ +} __attribute__ ((packed)); + +#endif /* GRUB_USBDESC_H */ diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h new file mode 100644 index 0000000..7e4a9d7 --- /dev/null +++ b/include/grub/usbtrans.h @@ -0,0 +1,107 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_USBTRANS_H +#define GRUB_USBTRANS_H 1 + +typedef enum + { + GRUB_USB_TRANSFER_TYPE_IN, + GRUB_USB_TRANSFER_TYPE_OUT, + GRUB_USB_TRANSFER_TYPE_SETUP + } grub_transfer_type_t; + +typedef enum + { + GRUB_USB_TRANSACTION_TYPE_CONTROL, + GRUB_USB_TRANSACTION_TYPE_BULK + } grub_transaction_type_t; + +struct grub_usb_transaction +{ + int size; + int toggle; + grub_transfer_type_t pid; + char *data; +}; +typedef struct grub_usb_transaction *grub_usb_transaction_t; + +struct grub_usb_transfer +{ + int devaddr; + + int endpoint; + + int size; + + int transcnt; + + int max; + + grub_transaction_type_t type; + + struct grub_usb_device *dev; + + struct grub_usb_transaction *transactions; +}; +typedef struct grub_usb_transfer *grub_usb_transfer_t; + + +#define GRUB_USB_REQTYPE_IN (1 << 7) +#define GRUB_USB_REQTYPE_OUT (0 << 7) +#define GRUB_USB_REQTYPE_STANDARD (0 << 5) +#define GRUB_USB_REQTYPE_CLASS (1 << 5) +#define GRUB_USB_REQTYPE_VENDOR (2 << 5) +#define GRUB_USB_REQTYPE_TARGET_DEV (0 << 0) +#define GRUB_USB_REQTYPE_TARGET_INTERF (1 << 0) +#define GRUB_USB_REQTYPE_TARGET_ENDP (2 << 0) +#define GRUB_USB_REQTYPE_TARGET_OTHER (3 << 0) + +#define GRUB_USB_REQ_GET_STATUS 0x00 +#define GRUB_USB_REQ_CLEAR_FEATURE 0x01 +#define GRUB_USB_REQ_SET_FEATURE 0x03 +#define GRUB_USB_REQ_SET_ADDRESS 0x05 +#define GRUB_USB_REQ_GET_DESCRIPTOR 0x06 +#define GRUB_USB_REQ_SET_DESCRIPTOR 0x07 +#define GRUB_USB_REQ_GET_CONFIGURATION 0x08 +#define GRUB_USB_REQ_SET_CONFIGURATION 0x09 +#define GRUB_USB_REQ_GET_INTERFACE 0x0A +#define GRUB_USB_REQ_SET_INTERFACE 0x0B +#define GRUB_USB_REQ_SYNC_FRAME 0x0C + +#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00 + +#define GRUB_USB_FEATURE_ENDP_HALT 0x01 +#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02 +#define GRUB_USB_FEATURE_TEST_MODE 0x04 + +#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) +#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) +#define GRUB_USB_HUB_STATUS_HIGHSPEED (1 << 10) + +struct grub_usb_packet_setup +{ + grub_uint8_t reqtype; + grub_uint8_t request; + grub_uint16_t value; + grub_uint16_t index; + grub_uint16_t length; +} __attribute__((packed)); + + +#endif /* GRUB_USBTRANS_H */ diff --git a/include/grub/util/getroot.h b/include/grub/util/getroot.h new file mode 100644 index 0000000..bf0c55c --- /dev/null +++ b/include/grub/util/getroot.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2007, 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_UTIL_GETROOT_HEADER +#define GRUB_UTIL_GETROOT_HEADER 1 + +enum grub_dev_abstraction_types { + GRUB_DEV_ABSTRACTION_NONE, + GRUB_DEV_ABSTRACTION_LVM, + GRUB_DEV_ABSTRACTION_RAID, +}; + +char *grub_guess_root_device (const char *dir); +char *grub_get_prefix (const char *dir); +int grub_util_get_dev_abstraction (const char *os_dev); +char *grub_util_get_grub_dev (const char *os_dev); +const char *grub_util_check_block_device (const char *blk_dev); + +#endif /* ! GRUB_UTIL_GETROOT_HEADER */ diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h new file mode 100644 index 0000000..21efb0d --- /dev/null +++ b/include/grub/util/hostdisk.h @@ -0,0 +1,27 @@ +/* biosdisk.h - emulate biosdisk */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER +#define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 + +void grub_util_biosdisk_init (const char *dev_map); +void grub_util_biosdisk_fini (void); +char *grub_util_biosdisk_get_grub_dev (const char *os_dev); + +#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/util/lvm.h b/include/grub/util/lvm.h new file mode 100644 index 0000000..7a4c76c --- /dev/null +++ b/include/grub/util/lvm.h @@ -0,0 +1,27 @@ +/* lvm.h - LVM support for GRUB utils. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LVM_UTIL_HEADER +#define GRUB_LVM_UTIL_HEADER 1 + +#ifdef __linux__ +int grub_util_lvm_isvolume (char *name); +#endif + +#endif /* ! GRUB_RAID_UTIL_HEADER */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h new file mode 100644 index 0000000..2e920c1 --- /dev/null +++ b/include/grub/util/misc.h @@ -0,0 +1,78 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_UTIL_MISC_HEADER +#define GRUB_UTIL_MISC_HEADER 1 + +#include +#include +#include +#include + +#include +#include + +#ifdef __NetBSD__ +/* NetBSD uses /boot for its boot block. */ +# define DEFAULT_DIRECTORY "/grub" +#else +# define DEFAULT_DIRECTORY "/boot/grub" +#endif + +#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" + +extern char *progname; +extern int verbosity; +extern jmp_buf main_env; + +void grub_util_info (const char *fmt, ...); +void grub_util_error (const char *fmt, ...) __attribute__ ((noreturn)); + +void *xmalloc (size_t size); +void *xrealloc (void *ptr, size_t size); +char *xstrdup (const char *str); + +char *grub_util_get_path (const char *dir, const char *file); +size_t grub_util_get_fp_size (FILE *fp); +size_t grub_util_get_image_size (const char *path); +void grub_util_read_at (void *img, size_t len, off_t offset, FILE *fp); +char *grub_util_read_image (const char *path); +void grub_util_load_image (const char *path, char *buf); +void grub_util_write_image (const char *img, size_t size, FILE *out); +void grub_util_write_image_at (const void *img, size_t size, off_t offset, + FILE *out); + +#ifndef HAVE_ASPRINTF + +int asprintf (char **buf, const char *fmt, ...); + +#endif + +#ifdef __MINGW32__ + +#define fseeko fseeko64 +#define ftello ftello64 + +void sync (void); +void sleep(int s); + +grub_int64_t grub_util_get_disk_size (char *name); + +#endif + +#endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/include/grub/util/raid.h b/include/grub/util/raid.h new file mode 100644 index 0000000..67020bb --- /dev/null +++ b/include/grub/util/raid.h @@ -0,0 +1,27 @@ +/* raid.h - RAID support for GRUB utils. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_RAID_UTIL_HEADER +#define GRUB_RAID_UTIL_HEADER 1 + +#ifdef __linux__ +char** grub_util_raid_getmembers (char *name); +#endif + +#endif /* ! GRUB_RAID_UTIL_HEADER */ diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h new file mode 100644 index 0000000..f42df32 --- /dev/null +++ b/include/grub/util/resolve.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_UTIL_RESOLVE_HEADER +#define GRUB_UTIL_RESOLVE_HEADER 1 + +struct grub_util_path_list +{ + const char *name; + struct grub_util_path_list *next; +}; + +/* Resolve the dependencies of the modules MODULES using the information + in the file DEP_LIST_FILE. The directory PREFIX is used to find files. */ +struct grub_util_path_list * +grub_util_resolve_dependencies (const char *prefix, + const char *dep_list_file, + char *modules[]); + +#endif /* ! GRUB_UTIL_RESOLVE_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h new file mode 100644 index 0000000..cb73dae --- /dev/null +++ b/include/grub/video.h @@ -0,0 +1,302 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VIDEO_HEADER +#define GRUB_VIDEO_HEADER 1 + +#include +#include + +/* Video color in hardware dependent format. Users should not assume any + specific coding format. */ +typedef grub_uint32_t grub_video_color_t; + +/* This structure is driver specific and should not be accessed directly by + outside code. */ +struct grub_video_render_target; + +/* Forward declarations for used data structures. */ +struct grub_video_bitmap; + +/* Defines used to describe video mode or rendering target. */ +#define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020 +#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010 +#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP 0x00000004 +#define GRUB_VIDEO_MODE_TYPE_INDEX_COLOR 0x00000002 +#define GRUB_VIDEO_MODE_TYPE_RGB 0x00000001 + +/* Defines used to mask flags. */ +#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK 0x0000000F + +/* Defines used to specify requested bit depth. */ +#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK 0x0000ff00 +#define GRUB_VIDEO_MODE_TYPE_DEPTH_POS 8 + +/* Defined predefined render targets. */ +#define GRUB_VIDEO_RENDER_TARGET_DISPLAY ((struct grub_video_render_target *) 0) +#define GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER ((struct grub_video_render_target *) 0) +#define GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER ((struct grub_video_render_target *) 1) + +/* Defined blitting formats. */ +enum grub_video_blit_format + { + /* Generic RGBA, use fields & masks. */ + GRUB_VIDEO_BLIT_FORMAT_RGBA, + + /* Optimized RGBA's. */ + GRUB_VIDEO_BLIT_FORMAT_RGBA_8888, + GRUB_VIDEO_BLIT_FORMAT_BGRA_8888, + + /* Generic RGB, use fields & masks. */ + GRUB_VIDEO_BLIT_FORMAT_RGB, + + /* Optimized RGB's. */ + GRUB_VIDEO_BLIT_FORMAT_RGB_888, + GRUB_VIDEO_BLIT_FORMAT_BGR_888, + GRUB_VIDEO_BLIT_FORMAT_RGB_565, + GRUB_VIDEO_BLIT_FORMAT_BGR_565, + + /* When needed, decode color or just use value as is. */ + GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR, + + /* Two color bitmap; bits packed: rows are not padded to byte boundary. */ + GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED + }; + +/* Define blitting operators. */ +enum grub_video_blit_operators + { + /* Replace target bitmap data with source. */ + GRUB_VIDEO_BLIT_REPLACE, + /* Blend target and source based on source's alpha value. */ + GRUB_VIDEO_BLIT_BLEND + }; + +struct grub_video_mode_info +{ + /* Width of the screen. */ + unsigned int width; + + /* Height of the screen. */ + unsigned int height; + + /* Mode type bitmask. Contains information like is it Index color or + RGB mode. */ + unsigned int mode_type; + + /* Bits per pixel. */ + unsigned int bpp; + + /* Bytes per pixel. */ + unsigned int bytes_per_pixel; + + /* Pitch of one scanline. How many bytes there are for scanline. */ + unsigned int pitch; + + /* In index color mode, number of colors. In RGB mode this is 256. */ + unsigned int number_of_colors; + + /* Optimization hint how binary data is coded. */ + enum grub_video_blit_format blit_format; + + /* How many bits are reserved for red color. */ + unsigned int red_mask_size; + + /* What is location of red color bits. In Index Color mode, this is 0. */ + unsigned int red_field_pos; + + /* How many bits are reserved for green color. */ + unsigned int green_mask_size; + + /* What is location of green color bits. In Index Color mode, this is 0. */ + unsigned int green_field_pos; + + /* How many bits are reserved for blue color. */ + unsigned int blue_mask_size; + + /* What is location of blue color bits. In Index Color mode, this is 0. */ + unsigned int blue_field_pos; + + /* How many bits are reserved in color. */ + unsigned int reserved_mask_size; + + /* What is location of reserved color bits. In Index Color mode, + this is 0. */ + unsigned int reserved_field_pos; + + /* For 1-bit bitmaps, the background color. Used for bits = 0. */ + grub_uint8_t bg_red; + grub_uint8_t bg_green; + grub_uint8_t bg_blue; + grub_uint8_t bg_alpha; + + /* For 1-bit bitmaps, the foreground color. Used for bits = 1. */ + grub_uint8_t fg_red; + grub_uint8_t fg_green; + grub_uint8_t fg_blue; + grub_uint8_t fg_alpha; +}; + +struct grub_video_palette_data +{ + grub_uint8_t r; /* Red color value (0-255). */ + grub_uint8_t g; /* Green color value (0-255). */ + grub_uint8_t b; /* Blue color value (0-255). */ + grub_uint8_t a; /* Reserved bits value (0-255). */ +}; + +struct grub_video_adapter +{ + /* The video adapter name. */ + const char *name; + + /* Initialize the video adapter. */ + grub_err_t (*init) (void); + + /* Clean up the video adapter. */ + grub_err_t (*fini) (void); + + grub_err_t (*setup) (unsigned int width, unsigned int height, + unsigned int mode_type); + + grub_err_t (*get_info) (struct grub_video_mode_info *mode_info); + + grub_err_t (*set_palette) (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + + grub_err_t (*get_palette) (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + + grub_err_t (*set_viewport) (unsigned int x, unsigned int y, + unsigned int width, unsigned int height); + + grub_err_t (*get_viewport) (unsigned int *x, unsigned int *y, + unsigned int *width, unsigned int *height); + + grub_video_color_t (*map_color) (grub_uint32_t color_name); + + grub_video_color_t (*map_rgb) (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue); + + grub_video_color_t (*map_rgba) (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue, grub_uint8_t alpha); + + grub_err_t (*unmap_color) (grub_video_color_t color, + grub_uint8_t *red, grub_uint8_t *green, + grub_uint8_t *blue, grub_uint8_t *alpha); + + grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y, + unsigned int width, unsigned int height); + + grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height); + + grub_err_t (*blit_render_target) (struct grub_video_render_target *source, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height); + + grub_err_t (*scroll) (grub_video_color_t color, int dx, int dy); + + grub_err_t (*swap_buffers) (void); + + grub_err_t (*create_render_target) (struct grub_video_render_target **result, + unsigned int width, unsigned int height, + unsigned int mode_type); + + grub_err_t (*delete_render_target) (struct grub_video_render_target *target); + + grub_err_t (*set_active_render_target) (struct grub_video_render_target *target); + + grub_err_t (*get_active_render_target) (struct grub_video_render_target **target); + + /* The next video adapter. */ + struct grub_video_adapter *next; +}; +typedef struct grub_video_adapter *grub_video_adapter_t; + +void grub_video_register (grub_video_adapter_t adapter); +void grub_video_unregister (grub_video_adapter_t adapter); +void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)); + +grub_err_t grub_video_setup (unsigned int width, unsigned int height, + unsigned int mode_type); + +grub_err_t grub_video_restore (void); + +grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info); + +enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info); + +grub_err_t grub_video_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + +grub_err_t grub_video_get_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + +grub_err_t grub_video_set_viewport (unsigned int x, unsigned int y, + unsigned int width, unsigned int height); + +grub_err_t grub_video_get_viewport (unsigned int *x, unsigned int *y, + unsigned int *width, unsigned int *height); + +grub_video_color_t grub_video_map_color (grub_uint32_t color_name); + +grub_video_color_t grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue); + +grub_video_color_t grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue, grub_uint8_t alpha); + +grub_err_t grub_video_unmap_color (grub_video_color_t color, + grub_uint8_t *red, grub_uint8_t *green, + grub_uint8_t *blue, grub_uint8_t *alpha); + +grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y, + unsigned int width, unsigned int height); + +grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height); + +grub_err_t grub_video_blit_render_target (struct grub_video_render_target *source, + enum grub_video_blit_operators oper, + int x, int y, + int offset_x, int offset_y, + unsigned int width, + unsigned int height); + +grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy); + +grub_err_t grub_video_swap_buffers (void); + +grub_err_t grub_video_create_render_target (struct grub_video_render_target **result, + unsigned int width, + unsigned int height, + unsigned int mode_type); + +grub_err_t grub_video_delete_render_target (struct grub_video_render_target *target); + +grub_err_t grub_video_set_active_render_target (struct grub_video_render_target *target); + +grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); + +#endif /* ! GRUB_VIDEO_HEADER */ diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h new file mode 100644 index 0000000..c0549f4 --- /dev/null +++ b/include/grub/x86_64/efi/kernel.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_KERNEL_HEADER +#define GRUB_MACHINE_KERNEL_HEADER 1 + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_MACHINE_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_MACHINE_DATA_END 0x50 + +#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ + diff --git a/include/grub/x86_64/efi/loader.h b/include/grub/x86_64/efi/loader.h new file mode 100644 index 0000000..4368a82 --- /dev/null +++ b/include/grub/x86_64/efi/loader.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include + +/* It is necessary to export these functions, because normal mode commands + reuse rescue mode commands. */ +void grub_rescue_cmd_linux (int argc, char *argv[]); +void grub_rescue_cmd_initrd (int argc, char *argv[]); + +void EXPORT_FUNC(grub_linux_real_boot) (void); + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/include/grub/x86_64/efi/machine.h b/include/grub/x86_64/efi/machine.h new file mode 100644 index 0000000..1600768 --- /dev/null +++ b/include/grub/x86_64/efi/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_EFI 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/x86_64/efi/time.h b/include/grub/x86_64/efi/time.h new file mode 100644 index 0000000..7a9241f --- /dev/null +++ b/include/grub/x86_64/efi/time.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_TIME_HEADER +#define GRUB_MACHINE_TIME_HEADER 1 + +#include + +#endif /* ! GRUB_MACHINE_TIME_HEADER */ diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h new file mode 100644 index 0000000..25ac57e --- /dev/null +++ b/include/grub/x86_64/kernel.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/x86_64/linux.h b/include/grub/x86_64/linux.h new file mode 100644 index 0000000..19ea936 --- /dev/null +++ b/include/grub/x86_64/linux.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include diff --git a/include/grub/x86_64/pci.h b/include/grub/x86_64/pci.h new file mode 100644 index 0000000..91a9924 --- /dev/null +++ b/include/grub/x86_64/pci.h @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include diff --git a/include/grub/x86_64/setjmp.h b/include/grub/x86_64/setjmp.h new file mode 100644 index 0000000..e417f65 --- /dev/null +++ b/include/grub/x86_64/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long grub_jmp_buf[8]; + +int grub_setjmp (grub_jmp_buf env); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/x86_64/time.h b/include/grub/x86_64/time.h new file mode 100644 index 0000000..842882c --- /dev/null +++ b/include/grub/x86_64/time.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* FIXME: this can't work until we handle interrupts. */ +/* __asm__ __volatile__ ("hlt"); */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/x86_64/types.h b/include/grub/x86_64/types.h new file mode 100644 index 0000000..bdee5a1 --- /dev/null +++ b/include/grub/x86_64/types.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* x86_64 is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/multiboot.h b/include/multiboot.h new file mode 100644 index 0000000..9adc873 --- /dev/null +++ b/include/multiboot.h @@ -0,0 +1,92 @@ +/* multiboot.h - multiboot header file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 + +/* The magic field should contain this. */ +#define MULTIBOOT_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_MAGIC2 0x2BADB002 + +/* The bits in the required part of flags field we don't support. */ +#define MULTIBOOT_UNSUPPORTED 0x0000fffc + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* + * Flags set in the 'flags' member of the multiboot header. + */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* + * Flags to be set in the 'flags' member of the multiboot info structure. + */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0x00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/include/multiboot2.h b/include/multiboot2.h new file mode 100644 index 0000000..0f2b0cf --- /dev/null +++ b/include/multiboot2.h @@ -0,0 +1,108 @@ +/* multiboot2.h - multiboot 2 header file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef MULTIBOOT2_HEADER +#define MULTIBOOT2_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT2_HEADER_SEARCH 8192 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* Passed from the bootloader to the kernel. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT2_MOD_ALIGN 0x00001000 + +#ifndef ASM_FILE + +#include "stdint.h" + +/* XXX not portable? */ +#if __WORDSIZE == 64 +typedef uint64_t multiboot_word; +#else +typedef uint32_t multiboot_word; +#endif + +struct multiboot_header +{ + uint32_t magic; + uint32_t flags; +}; + +struct multiboot_tag_header +{ + uint32_t key; + uint32_t len; +}; + +#define MULTIBOOT2_TAG_RESERVED1 0 +#define MULTIBOOT2_TAG_RESERVED2 (~0) + +#define MULTIBOOT2_TAG_START 1 +struct multiboot_tag_start +{ + struct multiboot_tag_header header; + multiboot_word size; /* Total size of all multiboot tags. */ +}; + +#define MULTIBOOT2_TAG_NAME 2 +struct multiboot_tag_name +{ + struct multiboot_tag_header header; + char name[1]; +}; + +#define MULTIBOOT2_TAG_MODULE 3 +struct multiboot_tag_module +{ + struct multiboot_tag_header header; + multiboot_word addr; + multiboot_word size; + char type[36]; + char cmdline[1]; +}; + +#define MULTIBOOT2_TAG_MEMORY 4 +struct multiboot_tag_memory +{ + struct multiboot_tag_header header; + multiboot_word addr; + multiboot_word size; + multiboot_word type; +}; + +#define MULTIBOOT2_TAG_UNUSED 5 +struct multiboot_tag_unused +{ + struct multiboot_tag_header header; +}; + +#define MULTIBOOT2_TAG_END 0xffff +struct multiboot_tag_end +{ + struct multiboot_tag_header header; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT2_HEADER */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..a5897de --- /dev/null +++ b/install-sh @@ -0,0 +1,519 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# 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 +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/io/bufio.c b/io/bufio.c new file mode 100644 index 0000000..92f2927 --- /dev/null +++ b/io/bufio.c @@ -0,0 +1,205 @@ +/* bufio.c - buffered io access */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define GRUB_BUFIO_DEF_SIZE 8192 +#define GRUB_BUFIO_MAX_SIZE 1048576 + +struct grub_bufio +{ + grub_file_t file; + grub_size_t block_size; + grub_size_t buffer_len; + char buffer[0]; +}; +typedef struct grub_bufio *grub_bufio_t; + +static struct grub_fs grub_bufio_fs; + +grub_file_t +grub_bufio_open (grub_file_t io, int size) +{ + grub_file_t file; + grub_bufio_t bufio = 0; + + file = (grub_file_t) grub_malloc (sizeof (*file)); + if (! file) + return 0; + + if (size == 0) + size = GRUB_BUFIO_DEF_SIZE; + else if (size > GRUB_BUFIO_MAX_SIZE) + size = GRUB_BUFIO_MAX_SIZE; + + if ((size < 0) || ((unsigned) size > io->size)) + size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE : + io->size); + + bufio = grub_malloc (sizeof (struct grub_bufio) + size); + if (! bufio) + { + grub_free (file); + return 0; + } + + bufio->file = io; + bufio->block_size = size; + bufio->buffer_len = 0; + + file->device = io->device; + file->offset = 0; + file->size = io->size; + file->data = bufio; + file->read_hook = 0; + file->fs = &grub_bufio_fs; + + return file; +} + +grub_file_t +grub_buffile_open (const char *name, int size) +{ + grub_file_t io, file; + + io = grub_file_open (name); + if (! io) + return 0; + + file = grub_bufio_open (io, size); + if (! file) + { + grub_file_close (io); + return 0; + } + + return file; +} + +static grub_ssize_t +grub_bufio_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_size_t res = len; + grub_bufio_t bufio = file->data; + grub_uint32_t pos; + + if ((file->offset >= bufio->file->offset) && + (file->offset < bufio->file->offset + bufio->buffer_len)) + { + grub_size_t n; + + pos = file->offset - bufio->file->offset; + n = bufio->buffer_len - pos; + if (n > len) + n = len; + + grub_memcpy (buf, &bufio->buffer[pos], n); + len -= n; + if (! len) + return res; + + buf += n; + bufio->file->offset += bufio->buffer_len; + pos = 0; + } + else + { + bufio->file->offset = grub_divmod64 (file->offset, bufio->block_size, + &pos); + bufio->file->offset *= bufio->block_size; + } + + if (pos + len >= bufio->block_size) + { + if (pos) + { + grub_size_t n; + + bufio->file->fs->read (bufio->file, bufio->buffer, + bufio->block_size); + if (grub_errno) + return -1; + + n = bufio->block_size - pos; + grub_memcpy (buf, &bufio->buffer[pos], n); + len -= n; + buf += n; + bufio->file->offset += bufio->block_size; + pos = 0; + } + + while (len >= bufio->block_size) + { + bufio->file->fs->read (bufio->file, buf, bufio->block_size); + if (grub_errno) + return -1; + + len -= bufio->block_size; + buf += bufio->block_size; + bufio->file->offset += bufio->block_size; + } + + if (! len) + { + bufio->buffer_len = 0; + return res; + } + } + + bufio->buffer_len = bufio->file->size - bufio->file->offset; + if (bufio->buffer_len > bufio->block_size) + bufio->buffer_len = bufio->block_size; + + bufio->file->fs->read (bufio->file, bufio->buffer, bufio->buffer_len); + if (grub_errno) + return -1; + + grub_memcpy (buf, &bufio->buffer[pos], len); + + return res; +} + +static grub_err_t +grub_bufio_close (grub_file_t file) +{ + grub_bufio_t bufio = file->data; + + grub_file_close (bufio->file); + grub_free (bufio); + + file->device = 0; + + return grub_errno; +} + +static struct grub_fs grub_bufio_fs = + { + .name = "bufio", + .dir = 0, + .open = 0, + .read = grub_bufio_read, + .close = grub_bufio_close, + .label = 0, + .next = 0 + }; diff --git a/io/gzio.c b/io/gzio.c new file mode 100644 index 0000000..0fada6c --- /dev/null +++ b/io/gzio.c @@ -0,0 +1,1243 @@ +/* gzio.c - decompression support for gzip */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * Most of this file was originally the source file "inflate.c", written + * by Mark Adler. It has been very heavily modified. In particular, the + * original would run through the whole file at once, and this version can + * be stopped and restarted on any boundary during the decompression process. + * + * The license and header comments that file are included here. + */ + +/* inflate.c -- Not copyrighted 1992 by Mark Adler + version c10p1, 10 January 1993 */ + +/* You can do whatever you like with this source file, though I would + prefer that if you modify it and redistribute it that you include + comments to that effect with your name and the date. Thank you. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Window Size + * + * This must be a power of two, and at least 32K for zip's deflate method + */ + +#define WSIZE 0x8000 + + +#define INBUFSIZ 0x2000 + +/* The state stored in filesystem-specific data. */ +struct grub_gzio +{ + /* The underlying file object. */ + grub_file_t file; + /* The offset at which the data starts in the underlying file. */ + grub_off_t data_offset; + /* The type of current block. */ + int block_type; + /* The length of current block. */ + int block_len; + /* The flag of the last block. */ + int last_block; + /* The flag of codes. */ + int code_state; + /* The length of a copy. */ + unsigned inflate_n; + /* The index of a copy. */ + unsigned inflate_d; + /* The input buffer. */ + grub_uint8_t inbuf[INBUFSIZ]; + int inbuf_d; + /* The bit buffer. */ + unsigned long bb; + /* The bits in the bit buffer. */ + unsigned bk; + /* The sliding window in uncompressed data. */ + grub_uint8_t slide[WSIZE]; + /* Current position in the slide. */ + unsigned wp; + /* The literal/length code table. */ + struct huft *tl; + /* The distance code table. */ + struct huft *td; + /* The lookup bits for the literal/length code table. */ + int bl; + /* The lookup bits for the distance code table. */ + int bd; + /* The original offset value. */ + grub_off_t saved_offset; +}; +typedef struct grub_gzio *grub_gzio_t; + +/* Declare the filesystem structure for grub_gzio_open. */ +static struct grub_fs grub_gzio_fs; + +/* Function prototypes */ +static void initialize_tables (grub_file_t file); + +/* Eat variable-length header fields. */ +static int +eat_field (grub_file_t file, int len) +{ + char ch = 1; + int not_retval = 1; + + do + { + if (len >= 0) + { + if (! (len--)) + break; + } + else + { + if (! ch) + break; + } + } + while ((not_retval = grub_file_read (file, &ch, 1)) == 1); + + return ! not_retval; +} + + +/* Little-Endian defines for the 2-byte magic numbers for gzip files. */ +#define GZIP_MAGIC grub_le_to_cpu16 (0x8B1F) +#define OLD_GZIP_MAGIC grub_le_to_cpu16 (0x9E1F) + +/* Compression methods (see algorithm.doc) */ +#define STORED 0 +#define COMPRESSED 1 +#define PACKED 2 +#define LZHED 3 +/* methods 4 to 7 reserved */ +#define DEFLATED 8 +#define MAX_METHODS 9 + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define UNSUPPORTED_FLAGS (CONTINUATION | ENCRYPTED | RESERVED) + +/* inflate block codes */ +#define INFLATE_STORED 0 +#define INFLATE_FIXED 1 +#define INFLATE_DYNAMIC 2 + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +static int +test_header (grub_file_t file) +{ + unsigned char buf[10] __attribute__ ((aligned)); + grub_gzio_t gzio = file->data; + + if (grub_file_tell (gzio->file) != 0) + grub_file_seek (gzio->file, 0); + + /* + * This checks if the file is gzipped. If a problem occurs here + * (other than a real error with the disk) then we don't think it + * is a compressed file, and simply mark it as such. + */ + if (grub_file_read (gzio->file, (char *) buf, 10) != 10 + || ((*((grub_uint16_t *) buf) != GZIP_MAGIC) + && (*((grub_uint16_t *) buf) != OLD_GZIP_MAGIC))) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "no gzip magic found"); + return 0; + } + + /* + * This does consistency checking on the header data. If a + * problem occurs from here on, then we have corrupt or otherwise + * bad data, and the error should be reported to the user. + */ + if (buf[2] != DEFLATED + || (buf[3] & UNSUPPORTED_FLAGS) + || ((buf[3] & EXTRA_FIELD) + && (grub_file_read (gzio->file, (char *) buf, 2) != 2 + || eat_field (gzio->file, + grub_le_to_cpu16 (*((grub_uint16_t *) buf))))) + || ((buf[3] & ORIG_NAME) && eat_field (gzio->file, -1)) + || ((buf[3] & COMMENT) && eat_field (gzio->file, -1))) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, "unsupported gzip format"); + return 0; + } + + gzio->data_offset = grub_file_tell (gzio->file); + + grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8); + + if (grub_file_read (gzio->file, (char *) buf, 8) != 8) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format"); + return 0; + } + + /* FIXME: this does not handle files whose original size is over 4GB. + But how can we know the real original size? */ + file->size = grub_le_to_cpu32 (*((grub_uint32_t *) (buf + 4))); + + initialize_tables (file); + + return 1; +} + + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 + means that v is a literal, 16 < e < 32 means that v is a pointer to + the next table, which codes e - 16 bits, and lastly e == 99 indicates + an unused code. If a code with e == 99 is looked up, this implies an + error in the data. */ +struct huft +{ + uch e; /* number of extra bits or operation */ + uch b; /* number of bits in this code or subcode */ + union + { + ush n; /* literal, length base, or distance base */ + struct huft *t; /* pointer to next level of table */ + } + v; +}; + + +/* The inflate algorithm uses a sliding 32K byte window on the uncompressed + stream to find repeated byte strings. This is implemented here as a + circular buffer. The index is updated simply by incrementing and then + and'ing with 0x7fff (32K-1). */ +/* It is left to other modules to supply the 32K area. It is assumed + to be usable as if it were declared "uch slide[32768];" or as just + "uch *slide;" and then malloc'ed in the latter case. The definition + must be in unzip.h, included above. */ + + +/* Tables for deflate from PKZIP's appnote.txt. */ +static unsigned bitorder[] = +{ /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static ush cplens[] = +{ /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* note: see note #13 above about the 258 in this list. */ +static ush cplext[] = +{ /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */ +static ush cpdist[] = +{ /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +static ush cpdext[] = +{ /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +static int lbits = 9; /* bits in base literal/length lookup table */ +static int dbits = 6; /* bits in base distance lookup table */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */ +#define BMAX 16 /* maximum bit length of any code (16 for explode) */ +#define N_MAX 288 /* maximum number of codes in any set */ + + +/* Macros for inflate() bit peeking and grabbing. + The usage is: + + NEEDBITS(j) + x = b & mask_bits[j]; + DUMPBITS(j) + + where NEEDBITS makes sure that b has at least j bits in it, and + DUMPBITS removes the bits from b. The macros use the variable k + for the number of bits in b. Normally, b and k are register + variables for speed, and are initialized at the beginning of a + routine that uses these macros from a global bit buffer and count. + + If we assume that EOB will be the longest code, then we will never + ask for bits with NEEDBITS that are beyond the end of the stream. + So, NEEDBITS should not read any more bytes than are needed to + meet the request. Then no bytes need to be "returned" to the buffer + at the end of the last block. + + However, this assumption is not true for fixed blocks--the EOB code + is 7 bits, but the other literal/length codes can be 8 or 9 bits. + (The EOB code is shorter than other codes because fixed blocks are + generally short. So, while a block always has an EOB, many other + literal/length codes have a significantly lower probability of + showing up at all.) However, by making the first table have a + lookup of seven bits, the EOB code will be found in that first + lookup, and so will not require that too many bits be pulled from + the stream. + */ + +static ush mask_bits[] = +{ + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte(file))<>=(n);k-=(n);} while (0) + +static int +get_byte (grub_file_t file) +{ + grub_gzio_t gzio = file->data; + + if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset + || gzio->inbuf_d == INBUFSIZ) + { + gzio->inbuf_d = 0; + grub_file_read (gzio->file, (char *) gzio->inbuf, INBUFSIZ); + } + + return gzio->inbuf[gzio->inbuf_d++]; +} + +/* more function prototypes */ +static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *, + struct huft **, int *); +static int huft_free (struct huft *); +static int inflate_codes_in_window (grub_file_t); + + +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return zero on success, one if + the given code set is incomplete (the tables are still built in this + case), two if the input is invalid (all zero length codes or an + oversubscribed set of lengths), and three if not enough memory. */ + +static int +huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ + unsigned n, /* number of codes (assumed <= N_MAX) */ + unsigned s, /* number of simple-valued codes (0..s-1) */ + ush * d, /* list of base values for non-simple codes */ + ush * e, /* list of extra bits for non-simple codes */ + struct huft **t, /* result: starting table */ + int *m) /* maximum lookup bits, returns actual */ +{ + unsigned a; /* counter for codes of length k */ + unsigned c[BMAX + 1]; /* bit length count table */ + unsigned f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register unsigned i; /* counter, current code */ + register unsigned j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register unsigned *p; /* pointer into c[], b[], or v[] */ + register struct huft *q; /* points to current table */ + struct huft r; /* table entry for structure assignment */ + struct huft *u[BMAX]; /* table stack */ + unsigned v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + unsigned x[BMAX + 1]; /* bit offsets, then code stack */ + unsigned *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + unsigned z; /* number of entries in current table */ + + /* Generate counts for each bit length */ + grub_memset ((char *) c, 0, sizeof (c)); + p = b; + i = n; + do + { + c[*p]++; /* assume all entries <= BMAX */ + p++; /* Can't combine with above line (Solaris bug) */ + } + while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (struct huft *) NULL; + *m = 0; + return 0; + } + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((unsigned) l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((unsigned) l > i) + l = i; + *m = l; + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return 2; /* bad input: more codes than bits */ + if ((y -= c[i]) < 0) + return 2; + c[i] += y; + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; + xp = x + 2; + while (--i) + { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + /* Make a table of values in order of bit lengths */ + p = b; + i = 0; + do + { + if ((j = *p++) != 0) + v[x[j]++] = i; + } + while (++i < n); + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (struct huft *) NULL; /* just to keep compilers happy */ + q = (struct huft *) NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = (unsigned) (g - w)) > (unsigned) l ? (unsigned) l : z; /* upper limit on table size */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + q = (struct huft *) grub_malloc ((z + 1) * sizeof (struct huft)); + if (! q) + { + if (h) + huft_free (u[0]); + return 3; + } + + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->v.t)) = (struct huft *) NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.b = (uch) l; /* bits to dump before this table */ + r.e = (uch) (16 + j); /* bits in this table */ + r.v.t = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h - 1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.b = (uch) (k - w); + if (p >= v + n) + r.e = 99; /* out of values--invalid code */ + else if (*p < s) + { + r.e = (uch) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ + r.v.n = (ush) (*p); /* simple code is just the value */ + p++; /* one compiler does not like *p++ */ + } + else + { + r.e = (uch) e[*p - s]; /* non-simple--look up in lists */ + r.v.n = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + /* Return true (1) if we were given an incomplete table */ + return y != 0 && g != 1; +} + + +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +static int +huft_free (struct huft *t) +{ + register struct huft *p, *q; + + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != (struct huft *) NULL) + { + q = (--p)->v.t; + grub_free ((char *) p); + p = q; + } + return 0; +} + + +/* + * inflate (decompress) the codes in a deflated (compressed) block. + * Return an error code or zero if it all goes ok. + */ + +static int +inflate_codes_in_window (grub_file_t file) +{ + register unsigned e; /* table entry flag/number of extra bits */ + unsigned n, d; /* length and index for copy */ + unsigned w; /* current window position */ + struct huft *t; /* pointer to table entry */ + unsigned ml, md; /* masks for bl and bd bits */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + grub_gzio_t gzio = file->data; + + /* make local copies of globals */ + d = gzio->inflate_d; + n = gzio->inflate_n; + b = gzio->bb; /* initialize bit buffer */ + k = gzio->bk; + w = gzio->wp; /* initialize window position */ + + /* inflate the coded data */ + ml = mask_bits[gzio->bl]; /* precompute masks for speed */ + md = mask_bits[gzio->bd]; + for (;;) /* do until end of block */ + { + if (! gzio->code_state) + { + NEEDBITS ((unsigned) gzio->bl); + if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) + do + { + if (e == 99) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "an unused code found"); + return 1; + } + DUMPBITS (t->b); + e -= 16; + NEEDBITS (e); + } + while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); + DUMPBITS (t->b); + + if (e == 16) /* then it's a literal */ + { + gzio->slide[w++] = (uch) t->v.n; + if (w == WSIZE) + break; + } + else + /* it's an EOB or a length */ + { + /* exit if end of block */ + if (e == 15) + { + gzio->block_len = 0; + break; + } + + /* get length of block to copy */ + NEEDBITS (e); + n = t->v.n + ((unsigned) b & mask_bits[e]); + DUMPBITS (e); + + /* decode distance of block to copy */ + NEEDBITS ((unsigned) gzio->bd); + if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) + do + { + if (e == 99) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "an unused code found"); + return 1; + } + DUMPBITS (t->b); + e -= 16; + NEEDBITS (e); + } + while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) + > 16); + DUMPBITS (t->b); + NEEDBITS (e); + d = w - t->v.n - ((unsigned) b & mask_bits[e]); + DUMPBITS (e); + gzio->code_state++; + } + } + + if (gzio->code_state) + { + /* do the copy */ + do + { + n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n + : e); + + if (w - d >= e) + { + grub_memmove (gzio->slide + w, gzio->slide + d, e); + w += e; + d += e; + } + else + /* purposefully use the overlap for extra copies here!! */ + { + while (e--) + gzio->slide[w++] = gzio->slide[d++]; + } + + if (w == WSIZE) + break; + } + while (n); + + if (! n) + gzio->code_state--; + + /* did we break from the loop too soon? */ + if (w == WSIZE) + break; + } + } + + /* restore the globals from the locals */ + gzio->inflate_d = d; + gzio->inflate_n = n; + gzio->wp = w; /* restore global window pointer */ + gzio->bb = b; /* restore global bit buffer */ + gzio->bk = k; + + return ! gzio->block_len; +} + + +/* get header for an inflated type 0 (stored) block. */ + +static void +init_stored_block (grub_file_t file) +{ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + grub_gzio_t gzio = file->data; + + /* make local copies of globals */ + b = gzio->bb; /* initialize bit buffer */ + k = gzio->bk; + + /* go to byte boundary */ + DUMPBITS (k & 7); + + /* get the length and its complement */ + NEEDBITS (16); + gzio->block_len = ((unsigned) b & 0xffff); + DUMPBITS (16); + NEEDBITS (16); + if (gzio->block_len != (int) ((~b) & 0xffff)) + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "the length of a stored block does not match"); + DUMPBITS (16); + + /* restore global variables */ + gzio->bb = b; + gzio->bk = k; +} + + +/* get header for an inflated type 1 (fixed Huffman codes) block. We should + either replace this with a custom decoder, or at least precompute the + Huffman tables. */ + +static void +init_fixed_block (grub_file_t file) +{ + int i; /* temporary variable */ + unsigned l[288]; /* length list for huft_build */ + grub_gzio_t gzio = file->data; + + /* set up literal table */ + for (i = 0; i < 144; i++) + l[i] = 8; + for (; i < 256; i++) + l[i] = 9; + for (; i < 280; i++) + l[i] = 7; + for (; i < 288; i++) /* make a complete, but wrong code set */ + l[i] = 8; + gzio->bl = 7; + if (huft_build (l, 288, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "failed in building a Huffman code table"); + return; + } + + /* set up distance table */ + for (i = 0; i < 30; i++) /* make an incomplete code set */ + l[i] = 5; + gzio->bd = 5; + if (huft_build (l, 30, 0, cpdist, cpdext, &gzio->td, &gzio->bd) > 1) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "failed in building a Huffman code table"); + huft_free (gzio->tl); + gzio->tl = 0; + return; + } + + /* indicate we're now working on a block */ + gzio->code_state = 0; + gzio->block_len++; +} + + +/* get header for an inflated type 2 (dynamic Huffman codes) block. */ + +static void +init_dynamic_block (grub_file_t file) +{ + int i; /* temporary variables */ + unsigned j; + unsigned l; /* last length */ + unsigned m; /* mask for bit lengths table */ + unsigned n; /* number of lengths to get */ + unsigned nb; /* number of bit length codes */ + unsigned nl; /* number of literal/length codes */ + unsigned nd; /* number of distance codes */ + unsigned ll[286 + 30]; /* literal/length and distance code lengths */ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + grub_gzio_t gzio = file->data; + + /* make local bit buffer */ + b = gzio->bb; + k = gzio->bk; + + /* read in table lengths */ + NEEDBITS (5); + nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ + DUMPBITS (5); + NEEDBITS (5); + nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ + DUMPBITS (5); + NEEDBITS (4); + nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ + DUMPBITS (4); + if (nl > 286 || nd > 30) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too much data"); + return; + } + + /* read in bit-length-code lengths */ + for (j = 0; j < nb; j++) + { + NEEDBITS (3); + ll[bitorder[j]] = (unsigned) b & 7; + DUMPBITS (3); + } + for (; j < 19; j++) + ll[bitorder[j]] = 0; + + /* build decoding table for trees--single level, 7 bit lookup */ + gzio->bl = 7; + if (huft_build (ll, 19, 19, NULL, NULL, &gzio->tl, &gzio->bl) != 0) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "failed in building a Huffman code table"); + return; + } + + /* read in literal and distance code lengths */ + n = nl + nd; + m = mask_bits[gzio->bl]; + i = l = 0; + while ((unsigned) i < n) + { + NEEDBITS ((unsigned) gzio->bl); + j = (gzio->td = gzio->tl + ((unsigned) b & m))->b; + DUMPBITS (j); + j = gzio->td->v.n; + if (j < 16) /* length of code in bits (0..15) */ + ll[i++] = l = j; /* save last length in l */ + else if (j == 16) /* repeat last length 3 to 6 times */ + { + NEEDBITS (2); + j = 3 + ((unsigned) b & 3); + DUMPBITS (2); + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found"); + return; + } + while (j--) + ll[i++] = l; + } + else if (j == 17) /* 3 to 10 zero length codes */ + { + NEEDBITS (3); + j = 3 + ((unsigned) b & 7); + DUMPBITS (3); + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found"); + return; + } + while (j--) + ll[i++] = 0; + l = 0; + } + else + /* j == 18: 11 to 138 zero length codes */ + { + NEEDBITS (7); + j = 11 + ((unsigned) b & 0x7f); + DUMPBITS (7); + if ((unsigned) i + j > n) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, "too many codes found"); + return; + } + while (j--) + ll[i++] = 0; + l = 0; + } + } + + /* free decoding table for trees */ + huft_free (gzio->tl); + gzio->td = 0; + gzio->tl = 0; + + /* restore the global bit buffer */ + gzio->bb = b; + gzio->bk = k; + + /* build the decoding tables for literal/length and distance codes */ + gzio->bl = lbits; + if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0) + { + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "failed in building a Huffman code table"); + return; + } + gzio->bd = dbits; + if (huft_build (ll + nl, nd, 0, cpdist, cpdext, &gzio->td, &gzio->bd) != 0) + { + huft_free (gzio->tl); + gzio->tl = 0; + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "failed in building a Huffman code table"); + return; + } + + /* indicate we're now working on a block */ + gzio->code_state = 0; + gzio->block_len++; +} + + +static void +get_new_block (grub_file_t file) +{ + register ulg b; /* bit buffer */ + register unsigned k; /* number of bits in bit buffer */ + grub_gzio_t gzio = file->data; + + /* make local bit buffer */ + b = gzio->bb; + k = gzio->bk; + + /* read in last block bit */ + NEEDBITS (1); + gzio->last_block = (int) b & 1; + DUMPBITS (1); + + /* read in block type */ + NEEDBITS (2); + gzio->block_type = (unsigned) b & 3; + DUMPBITS (2); + + /* restore the global bit buffer */ + gzio->bb = b; + gzio->bk = k; + + switch (gzio->block_type) + { + case INFLATE_STORED: + init_stored_block (file); + break; + case INFLATE_FIXED: + init_fixed_block (file); + break; + case INFLATE_DYNAMIC: + init_dynamic_block (file); + break; + default: + break; + } +} + + +static void +inflate_window (grub_file_t file) +{ + grub_gzio_t gzio = file->data; + + /* initialize window */ + gzio->wp = 0; + + /* + * Main decompression loop. + */ + + while (gzio->wp < WSIZE && grub_errno == GRUB_ERR_NONE) + { + if (! gzio->block_len) + { + if (gzio->last_block) + break; + + get_new_block (file); + } + + if (gzio->block_type > INFLATE_DYNAMIC) + grub_error (GRUB_ERR_BAD_GZIP_DATA, + "unknown block type %d", gzio->block_type); + + if (grub_errno != GRUB_ERR_NONE) + return; + + /* + * Expand stored block here. + */ + if (gzio->block_type == INFLATE_STORED) + { + int w = gzio->wp; + + /* + * This is basically a glorified pass-through + */ + + while (gzio->block_len && w < WSIZE && grub_errno == GRUB_ERR_NONE) + { + gzio->slide[w++] = get_byte (file); + gzio->block_len--; + } + + gzio->wp = w; + + continue; + } + + /* + * Expand other kind of block. + */ + + if (inflate_codes_in_window (file)) + { + huft_free (gzio->tl); + huft_free (gzio->td); + gzio->tl = 0; + gzio->td = 0; + } + } + + gzio->saved_offset += WSIZE; + + /* XXX do CRC calculation here! */ +} + + +static void +initialize_tables (grub_file_t file) +{ + grub_gzio_t gzio = file->data; + + gzio->saved_offset = 0; + grub_file_seek (gzio->file, gzio->data_offset); + + /* Initialize the bit buffer. */ + gzio->bk = 0; + gzio->bb = 0; + + /* Reset partial decompression code. */ + gzio->last_block = 0; + gzio->block_len = 0; + + /* Reset memory allocation stuff. */ + huft_free (gzio->tl); + huft_free (gzio->td); +} + + +/* Open a new decompressing object on the top of IO. If TRANSPARENT is true, + even if IO does not contain data compressed by gzip, return a valid file + object. Note that this function won't close IO, even if an error occurs. */ +grub_file_t +grub_gzio_open (grub_file_t io, int transparent) +{ + grub_file_t file; + grub_gzio_t gzio = 0; + + file = (grub_file_t) grub_malloc (sizeof (*file)); + if (! file) + return 0; + + gzio = grub_malloc (sizeof (*gzio)); + if (! gzio) + { + grub_free (file); + return 0; + } + + grub_memset (gzio, 0, sizeof (*gzio)); + gzio->file = io; + + file->device = io->device; + file->offset = 0; + file->data = gzio; + file->read_hook = 0; + file->fs = &grub_gzio_fs; + + if (! test_header (file)) + { + grub_free (gzio); + grub_free (file); + grub_file_seek (io, 0); + + if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && transparent) + { + grub_errno = GRUB_ERR_NONE; + return io; + } + else + return 0; + } + + return file; +} + +/* This is similar to grub_gzio_open, but takes a file name as an argument. */ +grub_file_t +grub_gzfile_open (const char *name, int transparent) +{ + grub_file_t io, file; + + io = grub_file_open (name); + if (! io) + return 0; + + file = grub_gzio_open (io, transparent); + if (! file) + { + grub_file_close (io); + return 0; + } + + return file; +} + +static grub_ssize_t +grub_gzio_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_ssize_t ret = 0; + grub_gzio_t gzio = file->data; + grub_off_t offset; + + /* Do we reset decompression to the beginning of the file? */ + if (gzio->saved_offset > file->offset + WSIZE) + initialize_tables (file); + + /* + * This loop operates upon uncompressed data only. The only + * special thing it does is to make sure the decompression + * window is within the range of data it needs. + */ + + offset = file->offset; + + while (len > 0 && grub_errno == GRUB_ERR_NONE) + { + register grub_size_t size; + register char *srcaddr; + + while (offset >= gzio->saved_offset) + inflate_window (file); + + srcaddr = (char *) ((offset & (WSIZE - 1)) + gzio->slide); + size = gzio->saved_offset - offset; + if (size > len) + size = len; + + grub_memmove (buf, srcaddr, size); + + buf += size; + len -= size; + ret += size; + offset += size; + } + + if (grub_errno != GRUB_ERR_NONE) + ret = -1; + + return ret; +} + +/* Release everything, including the underlying file object. */ +static grub_err_t +grub_gzio_close (grub_file_t file) +{ + grub_gzio_t gzio = file->data; + + grub_file_close (gzio->file); + huft_free (gzio->tl); + huft_free (gzio->td); + grub_free (gzio); + + /* No need to close the same device twice. */ + file->device = 0; + + return grub_errno; +} + + + +static struct grub_fs grub_gzio_fs = + { + .name = "gzio", + .dir = 0, + .open = 0, + .read = grub_gzio_read, + .close = grub_gzio_close, + .label = 0, + .next = 0 + }; diff --git a/kern/device.c b/kern/device.c new file mode 100644 index 0000000..60f25c1 --- /dev/null +++ b/kern/device.c @@ -0,0 +1,136 @@ +/* device.c - device manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +grub_device_t +grub_device_open (const char *name) +{ + grub_disk_t disk = 0; + grub_device_t dev = 0; + + if (! name) + { + name = grub_env_get ("root"); + if (*name == '\0') + { + grub_error (GRUB_ERR_BAD_DEVICE, "no device is set"); + goto fail; + } + } + + dev = grub_malloc (sizeof (*dev)); + if (! dev) + goto fail; + + /* Try to open a disk. */ + disk = grub_disk_open (name); + if (! disk) + goto fail; + + dev->disk = disk; + dev->net = 0; /* FIXME */ + + return dev; + + fail: + if (disk) + grub_disk_close (disk); + + grub_free (dev); + + return 0; +} + +grub_err_t +grub_device_close (grub_device_t device) +{ + if (device->disk) + grub_disk_close (device->disk); + + grub_free (device); + + return grub_errno; +} + +int +grub_device_iterate (int (*hook) (const char *name)) +{ + auto int iterate_disk (const char *disk_name); + auto int iterate_partition (grub_disk_t disk, + const grub_partition_t partition); + + int iterate_disk (const char *disk_name) + { + grub_device_t dev; + + if (hook (disk_name)) + return 1; + + dev = grub_device_open (disk_name); + if (! dev) + return 0; + + if (dev->disk && dev->disk->has_partitions) + if (grub_partition_iterate (dev->disk, iterate_partition)) + { + grub_device_close (dev); + return 1; + } + + grub_device_close (dev); + return 0; + } + + int iterate_partition (grub_disk_t disk, const grub_partition_t partition) + { + char *partition_name; + char *device_name; + int ret; + + partition_name = grub_partition_get_name (partition); + if (! partition_name) + return 1; + + device_name = grub_malloc (grub_strlen (disk->name) + 1 + + grub_strlen (partition_name) + 1); + if (! device_name) + { + grub_free (partition_name); + return 1; + } + + grub_sprintf (device_name, "%s,%s", disk->name, partition_name); + grub_free (partition_name); + + ret = hook (device_name); + grub_free (device_name); + return ret; + } + + /* Only disk devices are supported at the moment. */ + return grub_disk_dev_iterate (iterate_disk); +} diff --git a/kern/disk.c b/kern/disk.c new file mode 100644 index 0000000..4ee03e0 --- /dev/null +++ b/kern/disk.c @@ -0,0 +1,576 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_CACHE_TIMEOUT 2 + +/* The last time the disk was used. */ +static grub_uint64_t grub_last_time = 0; + + +/* Disk cache. */ +struct grub_disk_cache +{ + unsigned long dev_id; + unsigned long disk_id; + grub_disk_addr_t sector; + char *data; + int lock; +}; + +static struct grub_disk_cache grub_disk_cache_table[GRUB_DISK_CACHE_NUM]; + +void (*grub_disk_firmware_fini) (void); +int grub_disk_firmware_is_tainted; + +grub_err_t (* grub_disk_ata_pass_through) (grub_disk_t, + struct grub_disk_ata_pass_through_parms *); + + +#if 0 +static unsigned long grub_disk_cache_hits; +static unsigned long grub_disk_cache_misses; + +void +grub_disk_cache_get_performance (unsigned long *hits, unsigned long *misses) +{ + *hits = grub_disk_cache_hits; + *misses = grub_disk_cache_misses; +} +#endif + +static unsigned +grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + return ((dev_id * 524287UL + disk_id * 2606459UL + + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS))) + % GRUB_DISK_CACHE_NUM); +} + +static void +grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + unsigned index; + struct grub_disk_cache *cache; + + sector &= ~(GRUB_DISK_CACHE_SIZE - 1); + index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + index; + + if (cache->dev_id == dev_id && cache->disk_id == disk_id + && cache->sector == sector && cache->data) + { + cache->lock = 1; + grub_free (cache->data); + cache->data = 0; + cache->lock = 0; + } +} + +void +grub_disk_cache_invalidate_all (void) +{ + unsigned i; + + for (i = 0; i < GRUB_DISK_CACHE_NUM; i++) + { + struct grub_disk_cache *cache = grub_disk_cache_table + i; + + if (cache->data && ! cache->lock) + { + grub_free (cache->data); + cache->data = 0; + } + } +} + +static char * +grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + struct grub_disk_cache *cache; + unsigned index; + + index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + index; + + if (cache->dev_id == dev_id && cache->disk_id == disk_id + && cache->sector == sector) + { + cache->lock = 1; +#if 0 + grub_disk_cache_hits++; +#endif + return cache->data; + } + +#if 0 + grub_disk_cache_misses++; +#endif + + return 0; +} + +static void +grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector) +{ + struct grub_disk_cache *cache; + unsigned index; + + index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + index; + + if (cache->dev_id == dev_id && cache->disk_id == disk_id + && cache->sector == sector) + cache->lock = 0; +} + +static grub_err_t +grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id, + grub_disk_addr_t sector, const char *data) +{ + unsigned index; + struct grub_disk_cache *cache; + + grub_disk_cache_invalidate (dev_id, disk_id, sector); + + index = grub_disk_cache_get_index (dev_id, disk_id, sector); + cache = grub_disk_cache_table + index; + + cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + if (! cache->data) + return grub_errno; + + grub_memcpy (cache->data, data, + GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + cache->dev_id = dev_id; + cache->disk_id = disk_id; + cache->sector = sector; + + return GRUB_ERR_NONE; +} + + + +static grub_disk_dev_t grub_disk_dev_list; + +void +grub_disk_dev_register (grub_disk_dev_t dev) +{ + dev->next = grub_disk_dev_list; + grub_disk_dev_list = dev; +} + +void +grub_disk_dev_unregister (grub_disk_dev_t dev) +{ + grub_disk_dev_t *p, q; + + for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next) + if (q == dev) + { + *p = q->next; + break; + } +} + +int +grub_disk_dev_iterate (int (*hook) (const char *name)) +{ + grub_disk_dev_t p; + + for (p = grub_disk_dev_list; p; p = p->next) + if (p->iterate && (p->iterate) (hook)) + return 1; + + return 0; +} + +grub_disk_t +grub_disk_open (const char *name) +{ + char *p; + grub_disk_t disk; + grub_disk_dev_t dev; + char *raw = (char *) name; + grub_uint64_t current_time; + + grub_dprintf ("disk", "Opening `%s'...\n", name); + + disk = (grub_disk_t) grub_malloc (sizeof (*disk)); + if (! disk) + return 0; + + disk->dev = 0; + disk->read_hook = 0; + disk->partition = 0; + disk->data = 0; + disk->name = grub_strdup (name); + if (! disk->name) + goto fail; + + p = grub_strchr (name, ','); + if (p) + { + grub_size_t len = p - name; + + raw = grub_malloc (len + 1); + if (! raw) + goto fail; + + grub_memcpy (raw, name, len); + raw[len] = '\0'; + } + + for (dev = grub_disk_dev_list; dev; dev = dev->next) + { + if ((dev->open) (raw, disk) == GRUB_ERR_NONE) + break; + else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) + grub_errno = GRUB_ERR_NONE; + else + goto fail; + } + + if (! dev) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such disk"); + goto fail; + } + + if (p && ! disk->has_partitions) + { + grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk"); + goto fail; + } + + disk->dev = dev; + + if (p) + { + disk->partition = grub_partition_probe (disk, p + 1); + if (! disk->partition) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition"); + goto fail; + } + } + + /* The cache will be invalidated about 2 seconds after a device was + closed. */ + current_time = grub_get_time_ms (); + + if (current_time > (grub_last_time + + GRUB_CACHE_TIMEOUT * 1000)) + grub_disk_cache_invalidate_all (); + + grub_last_time = current_time; + + fail: + + if (raw && raw != name) + grub_free (raw); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_error_push (); + grub_dprintf ("disk", "Opening `%s' failed.\n", name); + grub_error_pop (); + + grub_disk_close (disk); + return 0; + } + + return disk; +} + +void +grub_disk_close (grub_disk_t disk) +{ + grub_dprintf ("disk", "Closing `%s'.\n", disk->name); + + if (disk->dev && disk->dev->close) + (disk->dev->close) (disk); + + /* Reset the timer. */ + grub_last_time = grub_get_time_ms (); + + grub_free (disk->partition); + grub_free ((void *) disk->name); + grub_free (disk); +} + +/* This function performs three tasks: + - Make sectors disk relative from partition relative. + - Normalize offset to be less than the sector size. + - Verify that the range is inside the partition. */ +static grub_err_t +grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector, + grub_off_t *offset, grub_size_t size) +{ + *sector += *offset >> GRUB_DISK_SECTOR_BITS; + *offset &= GRUB_DISK_SECTOR_SIZE - 1; + + if (disk->partition) + { + grub_disk_addr_t start; + grub_uint64_t len; + + start = grub_partition_get_start (disk->partition); + len = grub_partition_get_len (disk->partition); + + if (*sector >= len + || len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of partition"); + + *sector += start; + } + + if (disk->total_sectors <= *sector + || ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS) > disk->total_sectors - *sector) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk"); + + return GRUB_ERR_NONE; +} + +/* Read data from the disk. */ +grub_err_t +grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, char *buf) +{ + char *tmp_buf; + unsigned real_offset; + + grub_dprintf ("disk", "Reading `%s'...\n", disk->name); + + /* First of all, check if the region is within the disk. */ + if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) + { + grub_error_push (); + grub_dprintf ("disk", "Read out of range: sector 0x%llx (%s).\n", + (unsigned long long) sector, grub_errmsg); + grub_error_pop (); + return grub_errno; + } + + real_offset = offset; + + /* Allocate a temporary buffer. */ + tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS); + if (! tmp_buf) + return grub_errno; + + /* Until SIZE is zero... */ + while (size) + { + char *data; + grub_disk_addr_t start_sector; + grub_size_t len; + grub_size_t pos; + + /* For reading bulk data. */ + start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1); + pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS; + len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) + - pos - real_offset); + if (len > size) + len = size; + + /* Fetch the cache. */ + data = grub_disk_cache_fetch (disk->dev->id, disk->id, start_sector); + if (data) + { + /* Just copy it! */ + grub_memcpy (buf, data + pos + real_offset, len); + grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector); + } + else + { + /* Otherwise read data from the disk actually. */ + if ((disk->dev->read) (disk, start_sector, + GRUB_DISK_CACHE_SIZE, tmp_buf) + != GRUB_ERR_NONE) + { + /* Uggh... Failed. Instead, just read necessary data. */ + unsigned num; + char *p; + + grub_errno = GRUB_ERR_NONE; + + num = ((size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + + p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS); + if (!p) + goto finish; + + tmp_buf = p; + + if ((disk->dev->read) (disk, sector, num, tmp_buf)) + { + grub_error_push (); + grub_dprintf ("disk", "%s read failed\n", disk->name); + grub_error_pop (); + goto finish; + } + + grub_memcpy (buf, tmp_buf + real_offset, size); + + /* Call the read hook, if any. */ + if (disk->read_hook) + while (size) + { + (disk->read_hook) (sector, real_offset, + ((size > GRUB_DISK_SECTOR_SIZE) + ? GRUB_DISK_SECTOR_SIZE + : size)); + sector++; + size -= GRUB_DISK_SECTOR_SIZE - real_offset; + real_offset = 0; + } + + /* This must be the end. */ + goto finish; + } + + /* Copy it and store it in the disk cache. */ + grub_memcpy (buf, tmp_buf + pos + real_offset, len); + grub_disk_cache_store (disk->dev->id, disk->id, + start_sector, tmp_buf); + } + + /* Call the read hook, if any. */ + if (disk->read_hook) + { + grub_disk_addr_t s = sector; + grub_size_t l = len; + + while (l) + { + (disk->read_hook) (s, real_offset, + ((l > GRUB_DISK_SECTOR_SIZE) + ? GRUB_DISK_SECTOR_SIZE + : l)); + + if (l < GRUB_DISK_SECTOR_SIZE - real_offset) + break; + + s++; + l -= GRUB_DISK_SECTOR_SIZE - real_offset; + real_offset = 0; + } + } + + sector = start_sector + GRUB_DISK_CACHE_SIZE; + buf += len; + size -= len; + real_offset = 0; + } + + finish: + + grub_free (tmp_buf); + + return grub_errno; +} + +grub_err_t +grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, const char *buf) +{ + unsigned real_offset; + + grub_dprintf ("disk", "Writing `%s'...\n", disk->name); + + if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE) + return -1; + + real_offset = offset; + + while (size) + { + if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0)) + { + char tmp_buf[GRUB_DISK_SECTOR_SIZE]; + grub_size_t len; + + if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf) + != GRUB_ERR_NONE) + goto finish; + + len = GRUB_DISK_SECTOR_SIZE - real_offset; + if (len > size) + len = size; + + grub_memcpy (tmp_buf + real_offset, buf, len); + + grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); + + if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE) + goto finish; + + sector++; + buf += len; + size -= len; + real_offset = 0; + } + else + { + grub_size_t len; + grub_size_t n; + + len = size & ~(GRUB_DISK_SECTOR_SIZE - 1); + n = size >> GRUB_DISK_SECTOR_BITS; + + if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE) + goto finish; + + while (n--) + grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++); + + buf += len; + size -= len; + } + } + + finish: + + return grub_errno; +} + +grub_uint64_t +grub_disk_get_size (grub_disk_t disk) +{ + if (disk->partition) + return grub_partition_get_len (disk->partition); + else + return disk->total_sectors; +} diff --git a/kern/dl.c b/kern/dl.c new file mode 100644 index 0000000..bc21403 --- /dev/null +++ b/kern/dl.c @@ -0,0 +1,725 @@ +/* dl.c - loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + +typedef Elf32_Word Elf_Word; +typedef Elf32_Addr Elf_Addr; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Sym Elf_Sym; + +# define ELF_ST_BIND(val) ELF32_ST_BIND (val) +# define ELF_ST_TYPE(val) ELF32_ST_TYPE (val) + +#elif GRUB_CPU_SIZEOF_VOID_P == 8 + +typedef Elf64_Word Elf_Word; +typedef Elf64_Addr Elf_Addr; +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Sym Elf_Sym; + +# define ELF_ST_BIND(val) ELF64_ST_BIND (val) +# define ELF_ST_TYPE(val) ELF64_ST_TYPE (val) + +#endif + + + +struct grub_dl_list +{ + struct grub_dl_list *next; + grub_dl_t mod; +}; +typedef struct grub_dl_list *grub_dl_list_t; + +static grub_dl_list_t grub_dl_head; + +static grub_err_t +grub_dl_add (grub_dl_t mod) +{ + grub_dl_list_t l; + + if (grub_dl_get (mod->name)) + return grub_error (GRUB_ERR_BAD_MODULE, + "`%s' is already loaded", mod->name); + + l = (grub_dl_list_t) grub_malloc (sizeof (*l)); + if (! l) + return grub_errno; + + l->mod = mod; + l->next = grub_dl_head; + grub_dl_head = l; + + return GRUB_ERR_NONE; +} + +static void +grub_dl_remove (grub_dl_t mod) +{ + grub_dl_list_t *p, q; + + for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) + if (q->mod == mod) + { + *p = q->next; + grub_free (q); + return; + } +} + +grub_dl_t +grub_dl_get (const char *name) +{ + grub_dl_list_t l; + + for (l = grub_dl_head; l; l = l->next) + if (grub_strcmp (name, l->mod->name) == 0) + return l->mod; + + return 0; +} + +void +grub_dl_iterate (int (*hook) (grub_dl_t mod)) +{ + grub_dl_list_t l; + + for (l = grub_dl_head; l; l = l->next) + if (hook (l->mod)) + break; +} + + + +struct grub_symbol +{ + struct grub_symbol *next; + const char *name; + void *addr; + grub_dl_t mod; /* The module to which this symbol belongs. */ +}; +typedef struct grub_symbol *grub_symbol_t; + +/* The size of the symbol table. */ +#define GRUB_SYMTAB_SIZE 509 + +/* The symbol table (using an open-hash). */ +static struct grub_symbol *grub_symtab[GRUB_SYMTAB_SIZE]; + +/* Simple hash function. */ +static unsigned +grub_symbol_hash (const char *s) +{ + unsigned key = 0; + + while (*s) + key = key * 65599 + *s++; + + return (key + (key >> 5)) % GRUB_SYMTAB_SIZE; +} + +/* Resolve the symbol name NAME and return the address. + Return NULL, if not found. */ +void * +grub_dl_resolve_symbol (const char *name) +{ + grub_symbol_t sym; + + for (sym = grub_symtab[grub_symbol_hash (name)]; sym; sym = sym->next) + if (grub_strcmp (sym->name, name) == 0) + return sym->addr; + + return 0; +} + +/* Register a symbol with the name NAME and the address ADDR. */ +grub_err_t +grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod) +{ + grub_symbol_t sym; + unsigned k; + + sym = (grub_symbol_t) grub_malloc (sizeof (*sym)); + if (! sym) + return grub_errno; + + if (mod) + { + sym->name = grub_strdup (name); + if (! sym->name) + { + grub_free (sym); + return grub_errno; + } + } + else + sym->name = name; + + sym->addr = addr; + sym->mod = mod; + + k = grub_symbol_hash (name); + sym->next = grub_symtab[k]; + grub_symtab[k] = sym; + + return GRUB_ERR_NONE; +} + +/* Unregister all the symbols defined in the module MOD. */ +static void +grub_dl_unregister_symbols (grub_dl_t mod) +{ + unsigned i; + + if (! mod) + grub_fatal ("core symbols cannot be unregistered"); + + for (i = 0; i < GRUB_SYMTAB_SIZE; i++) + { + grub_symbol_t sym, *p, q; + + for (p = &grub_symtab[i], sym = *p; sym; sym = q) + { + q = sym->next; + if (sym->mod == mod) + { + *p = q; + grub_free ((void *) sym->name); + grub_free (sym); + } + else + p = &sym->next; + } + } +} + +/* Return the address of a section whose index is N. */ +static void * +grub_dl_get_section_addr (grub_dl_t mod, unsigned n) +{ + grub_dl_segment_t seg; + + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == n) + return seg->addr; + + return 0; +} + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_dl_check_header (void *ehdr, grub_size_t size) +{ + Elf_Ehdr *e = ehdr; + + /* Check the header size. */ + if (size < sizeof (Elf_Ehdr)) + return grub_error (GRUB_ERR_BAD_OS, "ELF header smaller than expected"); + + /* Check the magic numbers. */ + if (grub_arch_dl_check_header (ehdr) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_version != EV_CURRENT) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic"); + + return GRUB_ERR_NONE; +} + +/* Load all segments from memory specified by E. */ +static grub_err_t +grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) +{ + unsigned i; + Elf_Shdr *s; + + for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) + { + if (s->sh_flags & SHF_ALLOC) + { + grub_dl_segment_t seg; + + seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg)); + if (! seg) + return grub_errno; + + if (s->sh_size) + { + void *addr; + + addr = grub_memalign (s->sh_addralign, s->sh_size); + if (! addr) + { + grub_free (seg); + return grub_errno; + } + + switch (s->sh_type) + { + case SHT_PROGBITS: + grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size); + break; + case SHT_NOBITS: + grub_memset (addr, 0, s->sh_size); + break; + } + + seg->addr = addr; + } + else + seg->addr = 0; + + seg->size = s->sh_size; + seg->section = i; + seg->next = mod->segment; + mod->segment = seg; + } + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) +{ + unsigned i; + Elf_Shdr *s; + Elf_Sym *sym; + const char *str; + Elf_Word size, entsize; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symbol table"); + + sym = (Elf_Sym *) ((char *) e + s->sh_offset); + size = s->sh_size; + entsize = s->sh_entsize; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link); + str = (char *) e + s->sh_offset; + + for (i = 0; + i < size / entsize; + i++, sym = (Elf_Sym *) ((char *) sym + entsize)) + { + unsigned char type = ELF_ST_TYPE (sym->st_info); + unsigned char bind = ELF_ST_BIND (sym->st_info); + const char *name = str + sym->st_name; + + switch (type) + { + case STT_NOTYPE: + /* Resolve a global symbol. */ + if (sym->st_name != 0 && sym->st_shndx == 0) + { + sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); + if (! sym->st_value) + return grub_error (GRUB_ERR_BAD_MODULE, + "the symbol `%s' not found", name); + } + else + sym->st_value = 0; + break; + + case STT_OBJECT: + sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + if (bind != STB_LOCAL) + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; + break; + + case STT_FUNC: + sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + if (bind != STB_LOCAL) + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; + + if (grub_strcmp (name, "grub_mod_init") == 0) + mod->init = (void (*) (grub_dl_t)) sym->st_value; + else if (grub_strcmp (name, "grub_mod_fini") == 0) + mod->fini = (void (*) (void)) sym->st_value; + break; + + case STT_SECTION: + sym->st_value = (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + break; + + case STT_FILE: + sym->st_value = 0; + break; + + default: + return grub_error (GRUB_ERR_BAD_MODULE, + "unknown symbol type `%d'", (int) type); + } + } + + return GRUB_ERR_NONE; +} + +static void +grub_dl_call_init (grub_dl_t mod) +{ + if (mod->init) + (mod->init) (mod); +} + +static grub_err_t +grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); + str = (char *) e + s->sh_offset; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (grub_strcmp (str + s->sh_name, ".modname") == 0) + { + mod->name = grub_strdup ((char *) e + s->sh_offset); + if (! mod->name) + return grub_errno; + break; + } + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no module name found"); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); + str = (char *) e + s->sh_offset; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (grub_strcmp (str + s->sh_name, ".moddeps") == 0) + { + const char *name = (char *) e + s->sh_offset; + const char *max = name + s->sh_size; + + while ((name < max) && (*name)) + { + grub_dl_t m; + grub_dl_dep_t dep; + + m = grub_dl_load (name); + if (! m) + return grub_errno; + + grub_dl_ref (m); + + dep = (grub_dl_dep_t) grub_malloc (sizeof (*dep)); + if (! dep) + return grub_errno; + + dep->mod = m; + dep->next = mod->dep; + mod->dep = dep; + + name += grub_strlen (name) + 1; + } + } + + return GRUB_ERR_NONE; +} + +int +grub_dl_ref (grub_dl_t mod) +{ + grub_dl_dep_t dep; + + for (dep = mod->dep; dep; dep = dep->next) + grub_dl_ref (dep->mod); + + return ++mod->ref_count; +} + +int +grub_dl_unref (grub_dl_t mod) +{ + grub_dl_dep_t dep; + + for (dep = mod->dep; dep; dep = dep->next) + grub_dl_unref (dep->mod); + + return --mod->ref_count; +} + +static void +grub_dl_flush_cache (grub_dl_t mod) +{ + grub_dl_segment_t seg; + + for (seg = mod->segment; seg; seg = seg->next) { + if (seg->size) { + grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", + (unsigned long) seg->size, seg->addr); + grub_arch_sync_caches (seg->addr, seg->size); + } + } +} + +/* Load a module from core memory. */ +grub_dl_t +grub_dl_load_core (void *addr, grub_size_t size) +{ + Elf_Ehdr *e; + grub_dl_t mod; + + grub_dprintf ("modules", "module at %p, size 0x%lx\n", addr, + (unsigned long) size); + e = addr; + if (grub_dl_check_header (e, size)) + return 0; + + if (e->e_type != ET_REL) + { + grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type"); + return 0; + } + + /* Make sure that every section is within the core. */ + if (size < e->e_shoff + e->e_shentsize * e->e_shnum) + { + grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core"); + return 0; + } + + mod = (grub_dl_t) grub_malloc (sizeof (*mod)); + if (! mod) + return 0; + + mod->name = 0; + mod->ref_count = 1; + mod->dep = 0; + mod->segment = 0; + mod->init = 0; + mod->fini = 0; + + grub_dprintf ("modules", "relocating to %p\n", mod); + if (grub_dl_resolve_name (mod, e) + || grub_dl_resolve_dependencies (mod, e) + || grub_dl_load_segments (mod, e) + || grub_dl_resolve_symbols (mod, e) + || grub_arch_dl_relocate_symbols (mod, e)) + { + mod->fini = 0; + grub_dl_unload (mod); + return 0; + } + + grub_dl_flush_cache (mod); + + grub_dprintf ("modules", "module name: %s\n", mod->name); + grub_dprintf ("modules", "init function: %p\n", mod->init); + grub_dl_call_init (mod); + + if (grub_dl_add (mod)) + { + grub_dl_unload (mod); + return 0; + } + + return mod; +} + +/* Load a module from the file FILENAME. */ +grub_dl_t +grub_dl_load_file (const char *filename) +{ + grub_file_t file; + grub_ssize_t size; + void *core = 0; + grub_dl_t mod = 0; + + file = grub_file_open (filename); + if (! file) + return 0; + + size = grub_file_size (file); + core = grub_malloc (size); + if (! core) + goto failed; + + if (grub_file_read (file, core, size) != (int) size) + goto failed; + + mod = grub_dl_load_core (core, size); + if (! mod) + goto failed; + + mod->ref_count = 0; + + failed: + grub_file_close (file); + grub_free (core); + + return mod; +} + +/* Load a module using a symbolic name. */ +grub_dl_t +grub_dl_load (const char *name) +{ + char *filename; + grub_dl_t mod; + char *grub_dl_dir = grub_env_get ("prefix"); + + mod = grub_dl_get (name); + if (mod) + return mod; + + if (! grub_dl_dir) { + grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set"); + return 0; + } + + filename = (char *) grub_malloc (grub_strlen (grub_dl_dir) + 1 + + grub_strlen (name) + 4 + 1); + if (! filename) + return 0; + + grub_sprintf (filename, "%s/%s.mod", grub_dl_dir, name); + mod = grub_dl_load_file (filename); + grub_free (filename); + + if (! mod) + return 0; + + if (grub_strcmp (mod->name, name) != 0) + grub_error (GRUB_ERR_BAD_MODULE, "mismatched names"); + + return mod; +} + +/* Unload the module MOD. */ +int +grub_dl_unload (grub_dl_t mod) +{ + grub_dl_dep_t dep, depn; + grub_dl_segment_t seg, segn; + + if (mod->ref_count > 0) + return 0; + + if (mod->fini) + (mod->fini) (); + + grub_dl_remove (mod); + grub_dl_unregister_symbols (mod); + + for (dep = mod->dep; dep; dep = depn) + { + depn = dep->next; + + if (! grub_dl_unref (dep->mod)) + grub_dl_unload (dep->mod); + + grub_free (dep); + } + + for (seg = mod->segment; seg; seg = segn) + { + segn = seg->next; + grub_free (seg->addr); + grub_free (seg); + } + + grub_free (mod->name); + grub_free (mod); + return 1; +} + +/* Unload unneeded modules. */ +void +grub_dl_unload_unneeded (void) +{ + /* Because grub_dl_remove modifies the list of modules, this + implementation is tricky. */ + grub_dl_list_t p = grub_dl_head; + + while (p) + { + if (grub_dl_unload (p->mod)) + { + p = grub_dl_head; + continue; + } + + p = p->next; + } +} + +/* Unload all modules. */ +void +grub_dl_unload_all (void) +{ + while (grub_dl_head) + { + grub_dl_list_t p; + + grub_dl_unload_unneeded (); + + /* Force to decrement the ref count. This will purge pre-loaded + modules and manually inserted modules. */ + for (p = grub_dl_head; p; p = p->next) + p->mod->ref_count--; + } +} diff --git a/kern/efi/efi.c b/kern/efi/efi.c new file mode 100644 index 0000000..9c9a400 --- /dev/null +++ b/kern/efi/efi.c @@ -0,0 +1,736 @@ +/* efi.c - generic EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The handle of GRUB itself. Filled in by the startup code. */ +grub_efi_handle_t grub_efi_image_handle; + +/* The pointer to a system table. Filled in by the startup code. */ +grub_efi_system_table_t *grub_efi_system_table; + +static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID; +static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID; +static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; + +void * +grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration) +{ + void *interface; + grub_efi_status_t status; + + status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol, + protocol, registration, &interface); + if (status != GRUB_EFI_SUCCESS) + return 0; + + return interface; +} + +/* Return the array of handles which meet the requirement. If successful, + the number of handles is stored in NUM_HANDLES. The array is allocated + from the heap. */ +grub_efi_handle_t * +grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *num_handles) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_handle_t *buffer; + grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t); + + buffer = grub_malloc (buffer_size); + if (! buffer) + return 0; + + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + &buffer_size, buffer); + if (status == GRUB_EFI_BUFFER_TOO_SMALL) + { + grub_free (buffer); + buffer = grub_malloc (buffer_size); + if (! buffer) + return 0; + + status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + &buffer_size, buffer); + } + + if (status != GRUB_EFI_SUCCESS) + { + grub_free (buffer); + return 0; + } + + *num_handles = buffer_size / sizeof (grub_efi_handle_t); + return buffer; +} + +void * +grub_efi_open_protocol (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_uint32_t attributes) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + void *interface; + + b = grub_efi_system_table->boot_services; + status = efi_call_6 (b->open_protocol, handle, + protocol, + &interface, + grub_efi_image_handle, + 0, + attributes); + if (status != GRUB_EFI_SUCCESS) + return 0; + + return interface; +} + +int +grub_efi_set_text_mode (int on) +{ + grub_efi_console_control_protocol_t *c; + grub_efi_screen_mode_t mode, new_mode; + + c = grub_efi_locate_protocol (&console_control_guid, 0); + if (! c) + /* No console control protocol instance available, assume it is + already in text mode. */ + return 1; + + if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS) + return 0; + + new_mode = on ? GRUB_EFI_SCREEN_TEXT : GRUB_EFI_SCREEN_GRAPHICS; + if (mode != new_mode) + if (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS) + return 0; + + return 1; +} + +void +grub_efi_stall (grub_efi_uintn_t microseconds) +{ + efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds); +} + +grub_efi_loaded_image_t * +grub_efi_get_loaded_image (grub_efi_handle_t image_handle) +{ + return grub_efi_open_protocol (image_handle, + &loaded_image_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +void +grub_exit (void) +{ + grub_efi_fini (); + efi_call_4 (grub_efi_system_table->boot_services->exit, + grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); +} + +void +grub_reboot (void) +{ + grub_efi_fini (); + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); +} + +void +grub_halt (void) +{ + grub_efi_fini (); + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); +} + +int +grub_efi_exit_boot_services (grub_efi_uintn_t map_key) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + + b = grub_efi_system_table->boot_services; + status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key); + return status == GRUB_EFI_SUCCESS; +} + +grub_uint32_t +grub_get_rtc (void) +{ + grub_efi_time_t time; + grub_efi_runtime_services_t *r; + + r = grub_efi_system_table->runtime_services; + if (efi_call_2 (r->get_time, &time, 0) != GRUB_EFI_SUCCESS) + /* What is possible in this case? */ + return 0; + + return (((time.minute * 60 + time.second) * 1000 + + time.nanosecond / 1000000) + * GRUB_TICKS_PER_SECOND / 1000); +} + +/* Search the mods section from the PE32/PE32+ image. This code uses + a PE32 header, but should work with PE32+ as well. */ +grub_addr_t +grub_arch_modules_addr (void) +{ + grub_efi_loaded_image_t *image; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *coff_header; + struct grub_pe32_section_table *sections; + struct grub_pe32_section_table *section; + struct grub_module_info *info; + grub_uint16_t i; + + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (! image) + return 0; + + header = image->image_base; + coff_header = &(header->coff_header); + sections + = (struct grub_pe32_section_table *) ((char *) coff_header + + sizeof (*coff_header) + + coff_header->optional_header_size); + + for (i = 0, section = sections; + i < coff_header->num_sections; + i++, section++) + { + if (grub_strcmp (section->name, "mods") == 0) + break; + } + + if (i == coff_header->num_sections) + return 0; + + info = (struct grub_module_info *) ((char *) image->image_base + + section->virtual_address); + if (info->magic != GRUB_MODULE_MAGIC) + return 0; + + return (grub_addr_t) info; +} + +char * +grub_efi_get_filename (grub_efi_device_path_t *dp) +{ + char *name = 0; + + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + + if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) + break; + else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) + { + grub_efi_file_path_device_path_t *fp; + grub_efi_uint16_t len; + char *p; + grub_size_t size; + + if (name) + { + size = grub_strlen (name); + name[size] = '/'; + size++; + } + else + size = 0; + + len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) + / sizeof (grub_efi_char16_t)); + p = grub_realloc (name, size + len * 4 + 1); + if (! p) + { + grub_free (name); + return 0; + } + + name = p; + fp = (grub_efi_file_path_device_path_t *) dp; + *grub_utf16_to_utf8 ((grub_uint8_t *) name + size, + fp->path_name, len) = '\0'; + } + + dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); + } + + if (name) + { + /* EFI breaks paths with backslashes. */ + char *p; + + for (p = name; *p; p++) + if (*p == '\\') + *p = '/'; + } + + return name; +} + +grub_efi_device_path_t * +grub_efi_get_device_path (grub_efi_handle_t handle) +{ + return grub_efi_open_protocol (handle, &device_path_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +} + +/* Print the chain of Device Path nodes. This is mainly for debugging. */ +void +grub_efi_print_device_path (grub_efi_device_path_t *dp) +{ + while (1) + { + grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); + grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); + grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); + + switch (type) + { + case GRUB_EFI_END_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE: + grub_printf ("/EndEntire\n"); + //grub_putchar ('\n'); + break; + case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE: + grub_printf ("/EndThis\n"); + //grub_putchar ('\n'); + break; + default: + grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE: + { + grub_efi_pci_device_path_t pci; + grub_memcpy (&pci, dp, len); + grub_printf ("/PCI(%x,%x)", + (unsigned) pci.function, (unsigned) pci.device); + } + break; + case GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE: + { + grub_efi_pccard_device_path_t pccard; + grub_memcpy (&pccard, dp, len); + grub_printf ("/PCCARD(%x)", + (unsigned) pccard.function); + } + break; + case GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE: + { + grub_efi_memory_mapped_device_path_t mmapped; + grub_memcpy (&mmapped, dp, len); + grub_printf ("/MMap(%x,%llx,%llx)", + (unsigned) mmapped.memory_type, + (unsigned long long) mmapped.start_address, + (unsigned long long) mmapped.end_address); + } + break; + case GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE: + { + grub_efi_vendor_device_path_t vendor; + grub_memcpy (&vendor, dp, sizeof (vendor)); + grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + (unsigned) vendor.vendor_guid.data1, + (unsigned) vendor.vendor_guid.data2, + (unsigned) vendor.vendor_guid.data3, + (unsigned) vendor.vendor_guid.data4[0], + (unsigned) vendor.vendor_guid.data4[1], + (unsigned) vendor.vendor_guid.data4[2], + (unsigned) vendor.vendor_guid.data4[3], + (unsigned) vendor.vendor_guid.data4[4], + (unsigned) vendor.vendor_guid.data4[5], + (unsigned) vendor.vendor_guid.data4[6], + (unsigned) vendor.vendor_guid.data4[7]); + } + break; + case GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE: + { + grub_efi_controller_device_path_t controller; + grub_memcpy (&controller, dp, len); + grub_printf ("/Ctrl(%x)", + (unsigned) controller.controller_number); + } + break; + default: + grub_printf ("/UnknownHW(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_ACPI_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_acpi_device_path_t acpi; + grub_memcpy (&acpi, dp, len); + grub_printf ("/ACPI(%x,%x)", + (unsigned) acpi.hid, + (unsigned) acpi.uid); + } + break; + case GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_expanded_acpi_device_path_t eacpi; + grub_memcpy (&eacpi, dp, sizeof (eacpi)); + grub_printf ("/ACPI("); + + if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0') + grub_printf ("%x,", (unsigned) eacpi.hid); + else + grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)); + + if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0') + grub_printf ("%x,", (unsigned) eacpi.uid); + else + grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)); + + if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0') + grub_printf ("%x)", (unsigned) eacpi.cid); + else + grub_printf ("%s)", GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)); + } + break; + default: + grub_printf ("/UnknownACPI(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE: + { + grub_efi_atapi_device_path_t atapi; + grub_memcpy (&atapi, dp, len); + grub_printf ("/ATAPI(%x,%x,%x)", + (unsigned) atapi.primary_secondary, + (unsigned) atapi.slave_master, + (unsigned) atapi.lun); + } + break; + case GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE: + { + grub_efi_scsi_device_path_t scsi; + grub_memcpy (&scsi, dp, len); + grub_printf ("/SCSI(%x,%x)", + (unsigned) scsi.pun, + (unsigned) scsi.lun); + } + break; + case GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE: + { + grub_efi_fibre_channel_device_path_t fc; + grub_memcpy (&fc, dp, len); + grub_printf ("/FibreChannel(%llx,%llx)", + (unsigned long long) fc.wwn, + (unsigned long long) fc.lun); + } + break; + case GRUB_EFI_1394_DEVICE_PATH_SUBTYPE: + { + grub_efi_1394_device_path_t firewire; + grub_memcpy (&firewire, dp, len); + grub_printf ("/1394(%llx)", (unsigned long long) firewire.guid); + } + break; + case GRUB_EFI_USB_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_device_path_t usb; + grub_memcpy (&usb, dp, len); + grub_printf ("/USB(%x,%x)", + (unsigned) usb.parent_port_number, + (unsigned) usb.interface); + } + break; + case GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE: + { + grub_efi_usb_class_device_path_t usb_class; + grub_memcpy (&usb_class, dp, len); + grub_printf ("/USBClass(%x,%x,%x,%x,%x)", + (unsigned) usb_class.vendor_id, + (unsigned) usb_class.product_id, + (unsigned) usb_class.device_class, + (unsigned) usb_class.device_subclass, + (unsigned) usb_class.device_protocol); + } + break; + case GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE: + { + grub_efi_i2o_device_path_t i2o; + grub_memcpy (&i2o, dp, len); + grub_printf ("/I2O(%x)", (unsigned) i2o.tid); + } + break; + case GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE: + { + grub_efi_mac_address_device_path_t mac; + grub_memcpy (&mac, dp, len); + grub_printf ("/MacAddr(%02x:%02x:%02x:%02x:%02x:%02x,%x)", + (unsigned) mac.mac_address[0], + (unsigned) mac.mac_address[1], + (unsigned) mac.mac_address[2], + (unsigned) mac.mac_address[3], + (unsigned) mac.mac_address[4], + (unsigned) mac.mac_address[5], + (unsigned) mac.if_type); + } + break; + case GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE: + { + grub_efi_ipv4_device_path_t ipv4; + grub_memcpy (&ipv4, dp, len); + grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)", + (unsigned) ipv4.local_ip_address[0], + (unsigned) ipv4.local_ip_address[1], + (unsigned) ipv4.local_ip_address[2], + (unsigned) ipv4.local_ip_address[3], + (unsigned) ipv4.remote_ip_address[0], + (unsigned) ipv4.remote_ip_address[1], + (unsigned) ipv4.remote_ip_address[2], + (unsigned) ipv4.remote_ip_address[3], + (unsigned) ipv4.local_port, + (unsigned) ipv4.remote_port, + (unsigned) ipv4.protocol, + (unsigned) ipv4.static_ip_address); + } + break; + case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE: + { + grub_efi_ipv6_device_path_t ipv6; + grub_memcpy (&ipv6, dp, len); + grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)", + (unsigned) ipv6.local_ip_address[0], + (unsigned) ipv6.local_ip_address[1], + (unsigned) ipv6.local_ip_address[2], + (unsigned) ipv6.local_ip_address[3], + (unsigned) ipv6.local_ip_address[4], + (unsigned) ipv6.local_ip_address[5], + (unsigned) ipv6.local_ip_address[6], + (unsigned) ipv6.local_ip_address[7], + (unsigned) ipv6.remote_ip_address[0], + (unsigned) ipv6.remote_ip_address[1], + (unsigned) ipv6.remote_ip_address[2], + (unsigned) ipv6.remote_ip_address[3], + (unsigned) ipv6.remote_ip_address[4], + (unsigned) ipv6.remote_ip_address[5], + (unsigned) ipv6.remote_ip_address[6], + (unsigned) ipv6.remote_ip_address[7], + (unsigned) ipv6.local_port, + (unsigned) ipv6.remote_port, + (unsigned) ipv6.protocol, + (unsigned) ipv6.static_ip_address); + } + break; + case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE: + { + grub_efi_infiniband_device_path_t ib; + grub_memcpy (&ib, dp, len); + grub_printf ("/InfiniBand(%x,%llx,%llx,%llx)", + (unsigned) ib.port_gid[0], /* XXX */ + (unsigned long long) ib.remote_id, + (unsigned long long) ib.target_port_id, + (unsigned long long) ib.device_id); + } + break; + case GRUB_EFI_UART_DEVICE_PATH_SUBTYPE: + { + grub_efi_uart_device_path_t uart; + grub_memcpy (&uart, dp, len); + grub_printf ("/UART(%llu,%u,%x,%x)", + (unsigned long long) uart.baud_rate, + uart.data_bits, + uart.parity, + uart.stop_bits); + } + break; + case GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE: + { + grub_efi_vendor_messaging_device_path_t vendor; + grub_memcpy (&vendor, dp, sizeof (vendor)); + grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + (unsigned) vendor.vendor_guid.data1, + (unsigned) vendor.vendor_guid.data2, + (unsigned) vendor.vendor_guid.data3, + (unsigned) vendor.vendor_guid.data4[0], + (unsigned) vendor.vendor_guid.data4[1], + (unsigned) vendor.vendor_guid.data4[2], + (unsigned) vendor.vendor_guid.data4[3], + (unsigned) vendor.vendor_guid.data4[4], + (unsigned) vendor.vendor_guid.data4[5], + (unsigned) vendor.vendor_guid.data4[6], + (unsigned) vendor.vendor_guid.data4[7]); + } + break; + default: + grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_MEDIA_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: + { + grub_efi_hard_drive_device_path_t hd; + grub_memcpy (&hd, dp, len); + grub_printf ("/HD(%u,%llx,%llx,%02x%02x%02x%02x%02x%02x%02x%02x,%x,%x)", + hd.partition_number, + (unsigned long long) hd.partition_start, + (unsigned long long) hd.partition_size, + (unsigned) hd.partition_signature[0], + (unsigned) hd.partition_signature[1], + (unsigned) hd.partition_signature[2], + (unsigned) hd.partition_signature[3], + (unsigned) hd.partition_signature[4], + (unsigned) hd.partition_signature[5], + (unsigned) hd.partition_signature[6], + (unsigned) hd.partition_signature[7], + (unsigned) hd.mbr_type, + (unsigned) hd.signature_type); + } + break; + case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: + { + grub_efi_cdrom_device_path_t cd; + grub_memcpy (&cd, dp, len); + grub_printf ("/CD(%u,%llx,%llx)", + cd.boot_entry, + (unsigned long long) cd.partition_start, + (unsigned long long) cd.partition_size); + } + break; + case GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE: + { + grub_efi_vendor_media_device_path_t vendor; + grub_memcpy (&vendor, dp, sizeof (vendor)); + grub_printf ("/Vendor(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + (unsigned) vendor.vendor_guid.data1, + (unsigned) vendor.vendor_guid.data2, + (unsigned) vendor.vendor_guid.data3, + (unsigned) vendor.vendor_guid.data4[0], + (unsigned) vendor.vendor_guid.data4[1], + (unsigned) vendor.vendor_guid.data4[2], + (unsigned) vendor.vendor_guid.data4[3], + (unsigned) vendor.vendor_guid.data4[4], + (unsigned) vendor.vendor_guid.data4[5], + (unsigned) vendor.vendor_guid.data4[6], + (unsigned) vendor.vendor_guid.data4[7]); + } + break; + case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE: + { + grub_efi_file_path_device_path_t *fp; + grub_uint8_t buf[(len - 4) * 2 + 1]; + fp = (grub_efi_file_path_device_path_t *) dp; + *grub_utf16_to_utf8 (buf, fp->path_name, + (len - 4) / sizeof (grub_efi_char16_t)) + = '\0'; + grub_printf ("/File(%s)", buf); + } + break; + case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE: + { + grub_efi_protocol_device_path_t proto; + grub_memcpy (&proto, dp, sizeof (proto)); + grub_printf ("/Protocol(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)", + (unsigned) proto.guid.data1, + (unsigned) proto.guid.data2, + (unsigned) proto.guid.data3, + (unsigned) proto.guid.data4[0], + (unsigned) proto.guid.data4[1], + (unsigned) proto.guid.data4[2], + (unsigned) proto.guid.data4[3], + (unsigned) proto.guid.data4[4], + (unsigned) proto.guid.data4[5], + (unsigned) proto.guid.data4[6], + (unsigned) proto.guid.data4[7]); + } + break; + default: + grub_printf ("/UnknownMedia(%x)", (unsigned) subtype); + break; + } + break; + + case GRUB_EFI_BIOS_DEVICE_PATH_TYPE: + switch (subtype) + { + case GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE: + { + grub_efi_bios_device_path_t bios; + grub_memcpy (&bios, dp, sizeof (bios)); + grub_printf ("/BIOS(%x,%x,%s)", + (unsigned) bios.device_type, + (unsigned) bios.status_flags, + (char *) (dp + 1)); + } + break; + default: + grub_printf ("/UnknownBIOS(%x)", (unsigned) subtype); + break; + } + break; + + default: + grub_printf ("/UnknownType(%x,%x)\n", + (unsigned) type, + (unsigned) subtype); + return; + break; + } + + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; + + dp = (grub_efi_device_path_t *) ((char *) dp + len); + } +} diff --git a/kern/efi/init.c b/kern/efi/init.c new file mode 100644 index 0000000..115a087 --- /dev/null +++ b/kern/efi/init.c @@ -0,0 +1,87 @@ +/* init.c - generic EFI initialization and finalization */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void +grub_efi_init (void) +{ + /* First of all, initialize the console so that GRUB can display + messages. */ + grub_console_init (); + + /* Initialize the memory management system. */ + grub_efi_mm_init (); + + grub_efidisk_init (); +} + +void +grub_efi_set_prefix (void) +{ + grub_efi_loaded_image_t *image; + + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (image) + { + char *device; + char *file; + + device = grub_efidisk_get_device_name (image->device_handle); + file = grub_efi_get_filename (image->file_path); + + if (device && file) + { + char *p; + char *prefix; + + /* Get the directory. */ + p = grub_strrchr (file, '/'); + if (p) + *p = '\0'; + + prefix = grub_malloc (1 + grub_strlen (device) + 1 + + grub_strlen (file) + 1); + if (prefix) + { + grub_sprintf (prefix, "(%s)%s", device, file); + grub_env_set ("prefix", prefix); + grub_free (prefix); + } + } + + grub_free (device); + grub_free (file); + } +} + +void +grub_efi_fini (void) +{ + grub_efidisk_fini (); + grub_efi_mm_fini (); + grub_console_fini (); +} diff --git a/kern/efi/mm.c b/kern/efi/mm.c new file mode 100644 index 0000000..35b12ab --- /dev/null +++ b/kern/efi/mm.c @@ -0,0 +1,429 @@ +/* mm.c - generic EFI memory management */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +#define BYTES_TO_PAGES(bytes) ((bytes) >> 12) +#define PAGES_TO_BYTES(pages) ((pages) << 12) + +/* The size of a memory map obtained from the firmware. This must be + a multiplier of 4KB. */ +#define MEMORY_MAP_SIZE 0x3000 + +/* Maintain the list of allocated pages. */ +struct allocated_page +{ + grub_efi_physical_address_t addr; + grub_efi_uint64_t num_pages; +}; + +#define ALLOCATED_PAGES_SIZE 0x1000 +#define MAX_ALLOCATED_PAGES \ + (ALLOCATED_PAGES_SIZE / sizeof (struct allocated_page)) + +static struct allocated_page *allocated_pages = 0; + +/* The minimum and maximum heap size for GRUB itself. */ +#define MIN_HEAP_SIZE 0x100000 +#define MAX_HEAP_SIZE (16 * 0x100000) + + +/* Allocate pages. Return the pointer to the first of allocated pages. */ +void * +grub_efi_allocate_pages (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_allocate_type_t type; + grub_efi_status_t status; + grub_efi_boot_services_t *b; + +#if GRUB_TARGET_SIZEOF_VOID_P < 8 + /* Limit the memory access to less than 4GB for 32-bit platforms. */ + if (address > 0xffffffff) + return 0; + + if (address == 0) + { + type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; + address = 0xffffffff; + } + else + type = GRUB_EFI_ALLOCATE_ADDRESS; +#else + if (address == 0) + type = GRUB_EFI_ALLOCATE_ANY_PAGES; + else + type = GRUB_EFI_ALLOCATE_ADDRESS; +#endif + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (address == 0) + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ + address = 0xffffffff; + status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) + return 0; + } + + if (allocated_pages) + { + unsigned i; + + for (i = 0; i < MAX_ALLOCATED_PAGES; i++) + if (allocated_pages[i].addr == 0) + { + allocated_pages[i].addr = address; + allocated_pages[i].num_pages = pages; + break; + } + + if (i == MAX_ALLOCATED_PAGES) + grub_fatal ("too many page allocations"); + } + + return (void *) ((grub_addr_t) address); +} + +/* Free pages starting from ADDRESS. */ +void +grub_efi_free_pages (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + + if (allocated_pages + && ((grub_efi_physical_address_t) ((grub_addr_t) allocated_pages) + != address)) + { + unsigned i; + + for (i = 0; i < MAX_ALLOCATED_PAGES; i++) + if (allocated_pages[i].addr == address) + { + allocated_pages[i].addr = 0; + break; + } + } + + b = grub_efi_system_table->boot_services; + efi_call_2 (b->free_pages, address, pages); +} + +/* Get the memory map as defined in the EFI spec. Return 1 if successful, + return 0 if partial, or return -1 if an error occurs. */ +int +grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_uintn_t key; + grub_efi_uint32_t version; + + /* Allow some parameters to be missing. */ + if (! map_key) + map_key = &key; + if (! descriptor_version) + descriptor_version = &version; + + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key, + descriptor_size, descriptor_version); + if (status == GRUB_EFI_SUCCESS) + return 1; + else if (status == GRUB_EFI_BUFFER_TOO_SMALL) + return 0; + else + return -1; +} + +/* Sort the memory map in place. */ +static void +sort_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *d1; + grub_efi_memory_descriptor_t *d2; + + for (d1 = memory_map; + d1 < memory_map_end; + d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size)) + { + grub_efi_memory_descriptor_t *max_desc = d1; + + for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size); + d2 < memory_map_end; + d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size)) + { + if (max_desc->num_pages < d2->num_pages) + max_desc = d2; + } + + if (max_desc != d1) + { + grub_efi_memory_descriptor_t tmp; + + tmp = *d1; + *d1 = *max_desc; + *max_desc = tmp; + } + } +} + +/* Filter the descriptors. GRUB needs only available memory. */ +static grub_efi_memory_descriptor_t * +filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_memory_descriptor_t *filtered_memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_memory_descriptor_t *filtered_desc; + + for (desc = memory_map, filtered_desc = filtered_memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY +#if GRUB_TARGET_SIZEOF_VOID_P < 8 + && desc->physical_start <= 0xffffffff +#endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 + && desc->num_pages != 0) + { + grub_memcpy (filtered_desc, desc, desc_size); + + /* Avoid less than 1MB, because some loaders seem to be confused. */ + if (desc->physical_start < 0x100000) + { + desc->num_pages -= BYTES_TO_PAGES (0x100000 + - desc->physical_start); + desc->physical_start = 0x100000; + } + +#if GRUB_TARGET_SIZEOF_VOID_P < 8 + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages + > BYTES_TO_PAGES (0x100000000LL)) + filtered_desc->num_pages + = (BYTES_TO_PAGES (0x100000000LL) + - BYTES_TO_PAGES (filtered_desc->physical_start)); +#endif + + if (filtered_desc->num_pages == 0) + continue; + + filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size); + } + } + + return filtered_desc; +} + +/* Return the total number of pages. */ +static grub_efi_uint64_t +get_total_pages (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_uint64_t total = 0; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + total += desc->num_pages; + + return total; +} + +/* Add memory regions. */ +static void +add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end, + grub_efi_uint64_t required_pages) +{ + grub_efi_memory_descriptor_t *desc; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_uint64_t pages; + grub_efi_physical_address_t start; + void *addr; + + start = desc->physical_start; + pages = desc->num_pages; + if (pages > required_pages) + { + start += PAGES_TO_BYTES (pages - required_pages); + pages = required_pages; + } + + addr = grub_efi_allocate_pages (start, pages); + if (! addr) + grub_fatal ("cannot allocate conventional memory %p with %u pages", + (void *) ((grub_addr_t) start), + (unsigned) pages); + + grub_mm_init_region (addr, PAGES_TO_BYTES (pages)); + + required_pages -= pages; + if (required_pages == 0) + break; + } + + if (required_pages > 0) + grub_fatal ("too little memory"); +} + +#if 0 +/* Print the memory map. */ +static void +print_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + int i; + + for (desc = memory_map, i = 0; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++) + { + grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n", + desc->type, desc->physical_start, desc->virtual_start, + desc->num_pages, desc->attribute); + } +} +#endif + +void +grub_efi_mm_init (void) +{ + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; + grub_efi_memory_descriptor_t *filtered_memory_map; + grub_efi_memory_descriptor_t *filtered_memory_map_end; + grub_efi_uintn_t map_size; + grub_efi_uintn_t desc_size; + grub_efi_uint64_t total_pages; + grub_efi_uint64_t required_pages; + + /* First of all, allocate pages to maintain allocations. */ + allocated_pages + = grub_efi_allocate_pages (0, BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE)); + if (! allocated_pages) + grub_fatal ("cannot allocate memory"); + + grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE); + + /* Prepare a memory region to store two memory maps. */ + memory_map = grub_efi_allocate_pages (0, + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE); + + /* Obtain descriptors for available memory. */ + map_size = MEMORY_MAP_SIZE; + + if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) + grub_fatal ("cannot get memory map"); + + memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); + + filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, + desc_size, memory_map_end); + + /* By default, request a quarter of the available memory. */ + total_pages = get_total_pages (filtered_memory_map, desc_size, + filtered_memory_map_end); + required_pages = (total_pages >> 2); + if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); + else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE); + + /* Sort the filtered descriptors, so that GRUB can allocate pages + from smaller regions. */ + sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); + + /* Allocate memory regions for GRUB's memory management. */ + add_memory_regions (filtered_memory_map, desc_size, + filtered_memory_map_end, required_pages); + +#if 0 + /* For debug. */ + map_size = MEMORY_MAP_SIZE; + + if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) + grub_fatal ("cannot get memory map"); + + grub_printf ("printing memory map\n"); + print_memory_map (memory_map, desc_size, + NEXT_MEMORY_DESCRIPTOR (memory_map, map_size)); + grub_abort (); +#endif + + /* Release the memory maps. */ + grub_efi_free_pages ((grub_addr_t) memory_map, + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); +} + +void +grub_efi_mm_fini (void) +{ + if (allocated_pages) + { + unsigned i; + + for (i = 0; i < MAX_ALLOCATED_PAGES; i++) + { + struct allocated_page *p; + + p = allocated_pages + i; + if (p->addr != 0) + grub_efi_free_pages ((grub_addr_t) p->addr, p->num_pages); + } + + grub_efi_free_pages ((grub_addr_t) allocated_pages, + BYTES_TO_PAGES (ALLOCATED_PAGES_SIZE)); + } +} diff --git a/kern/elf.c b/kern/elf.c new file mode 100644 index 0000000..8ddf9e5 --- /dev/null +++ b/kern/elf.c @@ -0,0 +1,464 @@ +/* elf.c - load ELF files */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +static grub_err_t +grub_elf_check_header (grub_elf_t elf) +{ + Elf32_Ehdr *e = &elf->ehdr.ehdr32; + + if (e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_version != EV_CURRENT) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic"); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_elf_close (grub_elf_t elf) +{ + grub_file_t file = elf->file; + + grub_free (elf->phdrs); + grub_free (elf); + + if (file) + grub_file_close (file); + + return grub_errno; +} + +grub_elf_t +grub_elf_file (grub_file_t file) +{ + grub_elf_t elf; + + elf = grub_malloc (sizeof (*elf)); + if (! elf) + return 0; + + elf->file = file; + elf->phdrs = 0; + + if (grub_file_seek (elf->file, 0) == (grub_off_t) -1) + goto fail; + + if (grub_file_read (elf->file, (char *) &elf->ehdr, sizeof (elf->ehdr)) + != sizeof (elf->ehdr)) + { + grub_error_push (); + grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header."); + goto fail; + } + + if (grub_elf_check_header (elf)) + goto fail; + + return elf; + +fail: + grub_free (elf->phdrs); + grub_free (elf); + return 0; +} + +grub_elf_t +grub_elf_open (const char *name) +{ + grub_file_t file; + grub_elf_t elf; + + file = grub_gzfile_open (name, 1); + if (! file) + return 0; + + elf = grub_elf_file (file); + if (! elf) + grub_file_close (file); + + return elf; +} + + +/* 32-bit */ + +int +grub_elf_is_elf32 (grub_elf_t elf) +{ + return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32; +} + +static grub_err_t +grub_elf32_load_phdrs (grub_elf_t elf) +{ + grub_ssize_t phdrs_size; + + phdrs_size = elf->ehdr.ehdr32.e_phnum * elf->ehdr.ehdr32.e_phentsize; + + grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", + (unsigned long long) elf->ehdr.ehdr32.e_phoff, + (unsigned long) phdrs_size); + + elf->phdrs = grub_malloc (phdrs_size); + if (! elf->phdrs) + return grub_errno; + + if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1) + || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) + { + grub_error_push (); + return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers"); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_elf32_phdr_iterate (grub_elf_t elf, + int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *), + void *hook_arg) +{ + Elf32_Phdr *phdrs; + unsigned int i; + + if (! elf->phdrs) + if (grub_elf32_load_phdrs (elf)) + return grub_errno; + phdrs = elf->phdrs; + + for (i = 0; i < elf->ehdr.ehdr32.e_phnum; i++) + { + Elf32_Phdr *phdr = phdrs + i; + grub_dprintf ("elf", + "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx " + "filesz %lx\n", + i, phdr->p_type, + (unsigned long) phdr->p_paddr, + (unsigned long) phdr->p_memsz, + (unsigned long) phdr->p_filesz); + if (hook (elf, phdr, hook_arg)) + break; + } + + return grub_errno; +} + +/* Calculate the amount of memory spanned by the segments. */ +grub_size_t +grub_elf32_size (grub_elf_t elf) +{ + Elf32_Addr segments_start = (Elf32_Addr) -1; + Elf32_Addr segments_end = 0; + int nr_phdrs = 0; + + /* Run through the program headers to calculate the total memory size we + * should claim. */ + auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) + { + /* Only consider loadable segments. */ + if (phdr->p_type != PT_LOAD) + return 0; + nr_phdrs++; + if (phdr->p_paddr < segments_start) + segments_start = phdr->p_paddr; + if (phdr->p_paddr + phdr->p_memsz > segments_end) + segments_end = phdr->p_paddr + phdr->p_memsz; + return 0; + } + + grub_elf32_phdr_iterate (elf, calcsize, 0); + + if (nr_phdrs == 0) + { + grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + return 0; + } + + if (segments_end < segments_start) + { + /* Very bad addresses. */ + grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + return 0; + } + + return segments_end - segments_start; +} + + +/* Load every loadable segment into memory specified by `_load_hook'. */ +grub_err_t +grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, + grub_addr_t *base, grub_size_t *size) +{ + grub_addr_t load_base = (grub_addr_t) -1ULL; + grub_size_t load_size = 0; + grub_err_t err; + + auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook); + int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook) + { + grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook; + grub_addr_t load_addr; + + if (phdr->p_type != PT_LOAD) + return 0; + + load_addr = phdr->p_paddr; + if (load_hook && load_hook (phdr, &load_addr)) + return 1; + + if (load_addr < load_base) + load_base = load_addr; + + grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", + (unsigned long long) load_addr, + (unsigned long long) phdr->p_memsz); + + if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + } + + if (phdr->p_filesz) + { + grub_ssize_t read; + read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); + if (read != (grub_ssize_t) phdr->p_filesz) + { + /* XXX How can we free memory from `load_hook'? */ + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes.", + phdr->p_filesz, read); + } + } + + if (phdr->p_filesz < phdr->p_memsz) + grub_memset ((void *) (long) (load_addr + phdr->p_filesz), + 0, phdr->p_memsz - phdr->p_filesz); + + load_size += phdr->p_memsz; + + return 0; + } + + err = grub_elf32_phdr_iterate (_elf, grub_elf32_load_segment, _load_hook); + + if (base) + *base = load_base; + if (size) + *size = load_size; + + return err; +} + + + +/* 64-bit */ + +int +grub_elf_is_elf64 (grub_elf_t elf) +{ + return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64; +} + +static grub_err_t +grub_elf64_load_phdrs (grub_elf_t elf) +{ + grub_ssize_t phdrs_size; + + phdrs_size = elf->ehdr.ehdr64.e_phnum * elf->ehdr.ehdr64.e_phentsize; + + grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", + (unsigned long long) elf->ehdr.ehdr64.e_phoff, + (unsigned long) phdrs_size); + + elf->phdrs = grub_malloc (phdrs_size); + if (! elf->phdrs) + return grub_errno; + + if ((grub_file_seek (elf->file, elf->ehdr.ehdr64.e_phoff) == (grub_off_t) -1) + || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) + { + grub_error_push (); + return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers"); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_elf64_phdr_iterate (grub_elf_t elf, + int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *), + void *hook_arg) +{ + Elf64_Phdr *phdrs; + unsigned int i; + + if (! elf->phdrs) + if (grub_elf64_load_phdrs (elf)) + return grub_errno; + phdrs = elf->phdrs; + + for (i = 0; i < elf->ehdr.ehdr64.e_phnum; i++) + { + Elf64_Phdr *phdr = phdrs + i; + grub_dprintf ("elf", + "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx " + "filesz %lx\n", + i, phdr->p_type, + (unsigned long) phdr->p_paddr, + (unsigned long) phdr->p_memsz, + (unsigned long) phdr->p_filesz); + if (hook (elf, phdr, hook_arg)) + break; + } + + return grub_errno; +} + +/* Calculate the amount of memory spanned by the segments. */ +grub_size_t +grub_elf64_size (grub_elf_t elf) +{ + Elf64_Addr segments_start = (Elf64_Addr) -1; + Elf64_Addr segments_end = 0; + int nr_phdrs = 0; + + /* Run through the program headers to calculate the total memory size we + * should claim. */ + auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); + int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) + { + /* Only consider loadable segments. */ + if (phdr->p_type != PT_LOAD) + return 0; + nr_phdrs++; + if (phdr->p_paddr < segments_start) + segments_start = phdr->p_paddr; + if (phdr->p_paddr + phdr->p_memsz > segments_end) + segments_end = phdr->p_paddr + phdr->p_memsz; + return 0; + } + + grub_elf64_phdr_iterate (elf, calcsize, 0); + + if (nr_phdrs == 0) + { + grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + return 0; + } + + if (segments_end < segments_start) + { + /* Very bad addresses. */ + grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + return 0; + } + + return segments_end - segments_start; +} + + +/* Load every loadable segment into memory specified by `_load_hook'. */ +grub_err_t +grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook, + grub_addr_t *base, grub_size_t *size) +{ + grub_addr_t load_base = (grub_addr_t) -1ULL; + grub_size_t load_size = 0; + grub_err_t err; + + auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, + void *hook); + int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *hook) + { + grub_elf64_load_hook_t load_hook = (grub_elf64_load_hook_t) hook; + grub_addr_t load_addr; + + if (phdr->p_type != PT_LOAD) + return 0; + + load_addr = phdr->p_paddr; + if (load_hook && load_hook (phdr, &load_addr)) + return 1; + + if (load_addr < load_base) + load_base = load_addr; + + grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", + (unsigned long long) load_addr, + (unsigned long long) phdr->p_memsz); + + if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) + { + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Invalid offset in program header."); + } + + if (phdr->p_filesz) + { + grub_ssize_t read; + read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); + if (read != (grub_ssize_t) phdr->p_filesz) + { + /* XXX How can we free memory from `load_hook'? */ + grub_error_push (); + return grub_error (GRUB_ERR_BAD_OS, + "Couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes.", + phdr->p_filesz, read); + } + } + + if (phdr->p_filesz < phdr->p_memsz) + grub_memset ((void *) (long) (load_addr + phdr->p_filesz), + 0, phdr->p_memsz - phdr->p_filesz); + + load_size += phdr->p_memsz; + + return 0; + } + + err = grub_elf64_phdr_iterate (_elf, grub_elf64_load_segment, _load_hook); + + if (base) + *base = load_base; + if (size) + *size = load_size; + + return err; +} diff --git a/kern/env.c b/kern/env.c new file mode 100644 index 0000000..6a74c70 --- /dev/null +++ b/kern/env.c @@ -0,0 +1,428 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +/* The size of the hash table. */ +#define HASHSZ 13 + +/* A hashtable for quick lookup of variables. */ +struct grub_env_context +{ + /* A hash table for variables. */ + struct grub_env_var *vars[HASHSZ]; + + /* One level deeper on the stack. */ + struct grub_env_context *prev; +}; + +/* This is used for sorting only. */ +struct grub_env_sorted_var +{ + struct grub_env_var *var; + struct grub_env_sorted_var *next; +}; + +/* The initial context. */ +static struct grub_env_context initial_context; + +/* The current context. */ +static struct grub_env_context *current_context = &initial_context; + +/* Return the hash representation of the string S. */ +static unsigned int +grub_env_hashval (const char *s) +{ + unsigned int i = 0; + + /* XXX: This can be done much more efficiently. */ + while (*s) + i += 5 * *(s++); + + return i % HASHSZ; +} + +static struct grub_env_var * +grub_env_find (const char *name) +{ + struct grub_env_var *var; + int idx = grub_env_hashval (name); + + /* Look for the variable in the current context. */ + for (var = current_context->vars[idx]; var; var = var->next) + if (grub_strcmp (var->name, name) == 0) + return var; + + return 0; +} + +grub_err_t +grub_env_context_open (void) +{ + struct grub_env_context *context; + int i; + + context = grub_malloc (sizeof (*context)); + if (! context) + return grub_errno; + + grub_memset (context, 0, sizeof (*context)); + context->prev = current_context; + current_context = context; + + /* Copy exported variables. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = context->prev->vars[i]; var; var = var->next) + { + if (var->type == GRUB_ENV_VAR_GLOBAL) + { + if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_register_variable_hook (var->name, var->read_hook, var->write_hook); + } + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_context_close (void) +{ + struct grub_env_context *context; + int i; + + if (! current_context->prev) + grub_fatal ("cannot close the initial context"); + + /* Free the variables associated with this context. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *p, *q; + + for (p = current_context->vars[i]; p; p = q) + { + q = p->next; + grub_free (p); + } + } + + /* Restore the previous context. */ + context = current_context->prev; + grub_free (current_context); + current_context = context; + + return GRUB_ERR_NONE; +} + +static void +grub_env_insert (struct grub_env_context *context, + struct grub_env_var *var) +{ + int idx = grub_env_hashval (var->name); + + /* Insert the variable into the hashtable. */ + var->prevp = &context->vars[idx]; + var->next = context->vars[idx]; + if (var->next) + var->next->prevp = &(var->next); + context->vars[idx] = var; +} + +static void +grub_env_remove (struct grub_env_var *var) +{ + /* Remove the entry from the variable table. */ + *var->prevp = var->next; + if (var->next) + var->next->prevp = var->prevp; +} + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (var) + var->type = GRUB_ENV_VAR_GLOBAL; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_set (const char *name, const char *val) +{ + struct grub_env_var *var; + + /* If the variable does already exist, just update the variable. */ + var = grub_env_find (name); + if (var) + { + char *old = var->value; + + if (var->write_hook) + var->value = var->write_hook (var, val); + else + var->value = grub_strdup (val); + + if (! var->value) + { + var->value = old; + return grub_errno; + } + + grub_free (old); + return GRUB_ERR_NONE; + } + + /* The variable does not exist, so create a new one. */ + var = grub_malloc (sizeof (*var)); + if (! var) + return grub_errno; + + grub_memset (var, 0, sizeof (*var)); + + /* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave + this for readability. */ + var->type = GRUB_ENV_VAR_LOCAL; + + var->name = grub_strdup (name); + if (! var->name) + goto fail; + + var->value = grub_strdup (val); + if (! var->value) + goto fail; + + grub_env_insert (current_context, var); + + return GRUB_ERR_NONE; + + fail: + grub_free (var->name); + grub_free (var->value); + grub_free (var); + + return grub_errno; +} + +char * +grub_env_get (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (! var) + return 0; + + if (var->read_hook) + return var->read_hook (var, var->value); + + return var->value; +} + +void +grub_env_unset (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (! var) + return; + + /* XXX: It is not possible to unset variables with a read or write + hook. */ + if (var->read_hook || var->write_hook) + return; + + grub_env_remove (var); + + grub_free (var->name); + if (var->type != GRUB_ENV_VAR_DATA) + grub_free (var->value); + grub_free (var); +} + +void +grub_env_iterate (int (*func) (struct grub_env_var *var)) +{ + struct grub_env_sorted_var *sorted_list = 0; + struct grub_env_sorted_var *sorted_var; + int i; + + /* Add variables associated with this context into a sorted list. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = current_context->vars[i]; var; var = var->next) + { + struct grub_env_sorted_var *p, **q; + + /* Ignore data slots. */ + if (var->type == GRUB_ENV_VAR_DATA) + continue; + + sorted_var = grub_malloc (sizeof (*sorted_var)); + if (! sorted_var) + goto fail; + + sorted_var->var = var; + + for (q = &sorted_list, p = *q; p; q = &((*q)->next), p = *q) + { + if (grub_strcmp (p->var->name, var->name) > 0) + break; + } + + sorted_var->next = *q; + *q = sorted_var; + } + } + + /* Iterate FUNC on the sorted list. */ + for (sorted_var = sorted_list; sorted_var; sorted_var = sorted_var->next) + if (func (sorted_var->var)) + break; + + fail: + + /* Free the sorted list. */ + for (sorted_var = sorted_list; sorted_var; ) + { + struct grub_env_sorted_var *tmp = sorted_var->next; + + grub_free (sorted_var); + sorted_var = tmp; + } +} + +grub_err_t +grub_register_variable_hook (const char *name, + grub_env_read_hook_t read_hook, + grub_env_write_hook_t write_hook) +{ + struct grub_env_var *var = grub_env_find (name); + + if (! var) + { + if (grub_env_set (name, "") != GRUB_ERR_NONE) + return grub_errno; + + var = grub_env_find (name); + /* XXX Insert an assertion? */ + } + + var->read_hook = read_hook; + var->write_hook = write_hook; + + return GRUB_ERR_NONE; +} + +static char * +mangle_data_slot_name (const char *name) +{ + char *mangled_name; + + mangled_name = grub_malloc (grub_strlen (name) + 2); + if (! mangled_name) + return 0; + + grub_sprintf (mangled_name, "\e%s", name); + return mangled_name; +} + +grub_err_t +grub_env_set_data_slot (const char *name, const void *ptr) +{ + char *mangled_name; + struct grub_env_var *var; + + mangled_name = mangle_data_slot_name (name); + if (! mangled_name) + goto fail; + + /* If the variable does already exist, just update the variable. */ + var = grub_env_find (mangled_name); + if (var) + { + var->value = (char *) ptr; + return GRUB_ERR_NONE; + } + + /* The variable does not exist, so create a new one. */ + var = grub_malloc (sizeof (*var)); + if (! var) + goto fail; + + grub_memset (var, 0, sizeof (*var)); + + var->type = GRUB_ENV_VAR_DATA; + var->name = mangled_name; + var->value = (char *) ptr; + + grub_env_insert (current_context, var); + + return GRUB_ERR_NONE; + + fail: + + grub_free (mangled_name); + return grub_errno; +} + +void * +grub_env_get_data_slot (const char *name) +{ + char *mangled_name; + void *ptr = 0; + + mangled_name = mangle_data_slot_name (name); + if (! mangled_name) + goto fail; + + ptr = grub_env_get (mangled_name); + grub_free (mangled_name); + + fail: + + return ptr; +} + +void +grub_env_unset_data_slot (const char *name) +{ + char *mangled_name; + + mangled_name = mangle_data_slot_name (name); + if (! mangled_name) + return; + + grub_env_unset (mangled_name); + grub_free (mangled_name); +} diff --git a/kern/err.c b/kern/err.c new file mode 100644 index 0000000..8c78cb7 --- /dev/null +++ b/kern/err.c @@ -0,0 +1,134 @@ +/* err.c - error handling routines */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#define GRUB_MAX_ERRMSG 256 +#define GRUB_ERROR_STACK_SIZE 10 + +grub_err_t grub_errno; +char grub_errmsg[GRUB_MAX_ERRMSG]; + +static struct +{ + grub_err_t errno; + char errmsg[GRUB_MAX_ERRMSG]; +} grub_error_stack_items[GRUB_ERROR_STACK_SIZE]; + +static int grub_error_stack_pos; +static int grub_error_stack_assert; + +grub_err_t +grub_error (grub_err_t n, const char *fmt, ...) +{ + va_list ap; + + grub_errno = n; + + va_start (ap, fmt); + grub_vsprintf (grub_errmsg, fmt, ap); + va_end (ap); + + return n; +} + +void +grub_fatal (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + grub_vprintf (fmt, ap); + va_end (ap); + + grub_abort (); +} + +void +grub_error_push (void) +{ + /* Only add items to stack, if there is enough room. */ + if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE) + { + /* Copy active error message to stack. */ + grub_error_stack_items[grub_error_stack_pos].errno = grub_errno; + grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg, + grub_errmsg, + sizeof (grub_errmsg)); + + /* Advance to next error stack position. */ + grub_error_stack_pos++; + } + else + { + /* There is no room for new error message. Discard new error message + and mark error stack assertion flag. */ + grub_error_stack_assert = 1; + } + + /* Allow further operation of other components by resetting + active errno to GRUB_ERR_NONE. */ + grub_errno = GRUB_ERR_NONE; +} + +int +grub_error_pop (void) +{ + if (grub_error_stack_pos > 0) + { + /* Pop error message from error stack to current active error. */ + grub_error_stack_pos--; + + grub_errno = grub_error_stack_items[grub_error_stack_pos].errno; + grub_memcpy (grub_errmsg, + grub_error_stack_items[grub_error_stack_pos].errmsg, + sizeof (grub_errmsg)); + + return 1; + } + else + { + /* There is no more items on error stack, reset to no error state. */ + grub_errno = GRUB_ERR_NONE; + + return 0; + } +} + +void +grub_print_error (void) +{ + /* Print error messages in reverse order. First print active error message + and then empty error stack. */ + do + { + if (grub_errno != GRUB_ERR_NONE) + grub_err_printf ("error: %s\n", grub_errmsg); + } + while (grub_error_pop ()); + + /* If there was an assert while using error stack, report about it. */ + if (grub_error_stack_assert) + { + grub_err_printf ("assert: error stack overflow detected!\n"); + grub_error_stack_assert = 0; + } +} diff --git a/kern/file.c b/kern/file.c new file mode 100644 index 0000000..adf55da --- /dev/null +++ b/kern/file.c @@ -0,0 +1,162 @@ +/* file.c - file I/O functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Get the device part of the filename NAME. It is enclosed by parentheses. */ +char * +grub_file_get_device_name (const char *name) +{ + if (name[0] == '(') + { + char *p = grub_strchr (name, ')'); + char *ret; + + if (! p) + { + grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'"); + return 0; + } + + ret = (char *) grub_malloc (p - name); + if (! ret) + return 0; + + grub_memcpy (ret, name + 1, p - name - 1); + ret[p - name - 1] = '\0'; + return ret; + } + + return 0; +} + +grub_file_t +grub_file_open (const char *name) +{ + grub_device_t device; + grub_file_t file = 0; + char *device_name; + char *file_name; + + device_name = grub_file_get_device_name (name); + if (grub_errno) + return 0; + + /* Get the file part of NAME. */ + file_name = grub_strchr (name, ')'); + if (file_name) + file_name++; + else + file_name = (char *) name; + + device = grub_device_open (device_name); + grub_free (device_name); + if (! device) + goto fail; + + file = (grub_file_t) grub_malloc (sizeof (*file)); + if (! file) + goto fail; + + file->device = device; + file->offset = 0; + file->data = 0; + file->read_hook = 0; + + if (device->disk && file_name[0] != '/') + /* This is a block list. */ + file->fs = &grub_fs_blocklist; + else + { + file->fs = grub_fs_probe (device); + if (! file->fs) + goto fail; + } + + if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE) + goto fail; + + return file; + + fail: + if (device) + grub_device_close (device); + + /* if (net) grub_net_close (net); */ + + grub_free (file); + + return 0; +} + +grub_ssize_t +grub_file_read (grub_file_t file, char *buf, grub_size_t len) +{ + grub_ssize_t res; + + if (len == 0 || len > file->size - file->offset) + len = file->size - file->offset; + + /* Prevent an overflow. */ + if ((grub_ssize_t) len < 0) + len >>= 1; + + if (len == 0) + return 0; + + res = (file->fs->read) (file, buf, len); + if (res > 0) + file->offset += res; + + return res; +} + +grub_err_t +grub_file_close (grub_file_t file) +{ + if (file->fs->close) + (file->fs->close) (file); + + if (file->device) + grub_device_close (file->device); + grub_free (file); + return grub_errno; +} + +grub_off_t +grub_file_seek (grub_file_t file, grub_off_t offset) +{ + grub_off_t old; + + if (offset > file->size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + "attempt to seek outside of the file"); + return -1; + } + + old = file->offset; + file->offset = offset; + return old; +} diff --git a/kern/fs.c b/kern/fs.c new file mode 100644 index 0000000..4e21de2 --- /dev/null +++ b/kern/fs.c @@ -0,0 +1,263 @@ +/* fs.c - filesystem manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_fs_t grub_fs_list; + +grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; + +void +grub_fs_register (grub_fs_t fs) +{ + fs->next = grub_fs_list; + grub_fs_list = fs; +} + +void +grub_fs_unregister (grub_fs_t fs) +{ + grub_fs_t *p, q; + + for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next) + if (q == fs) + { + *p = q->next; + break; + } +} + +void +grub_fs_iterate (int (*hook) (const grub_fs_t fs)) +{ + grub_fs_t p; + + for (p = grub_fs_list; p; p = p->next) + if (hook (p)) + break; +} + +grub_fs_t +grub_fs_probe (grub_device_t device) +{ + grub_fs_t p; + auto int dummy_func (const char *filename, int dir); + + int dummy_func (const char *filename __attribute__ ((unused)), + int dir __attribute__ ((unused))) + { + return 1; + } + + if (device->disk) + { + /* Make it sure not to have an infinite recursive calls. */ + static int count = 0; + + for (p = grub_fs_list; p; p = p->next) + { + grub_dprintf ("fs", "Detecting %s...\n", p->name); + (p->dir) (device, "/", dummy_func); + if (grub_errno == GRUB_ERR_NONE) + return p; + + grub_error_push (); + grub_dprintf ("fs", "%s detection failed.\n", p->name); + grub_error_pop (); + + if (grub_errno != GRUB_ERR_BAD_FS) + return 0; + + grub_errno = GRUB_ERR_NONE; + } + + /* Let's load modules automatically. */ + if (grub_fs_autoload_hook && count == 0) + { + count++; + + while (grub_fs_autoload_hook ()) + { + p = grub_fs_list; + + (p->dir) (device, "/", dummy_func); + if (grub_errno == GRUB_ERR_NONE) + { + count--; + return p; + } + + if (grub_errno != GRUB_ERR_BAD_FS) + { + count--; + return 0; + } + + grub_errno = GRUB_ERR_NONE; + } + + count--; + } + } + else if (device->net->fs) + return device->net->fs; + + grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); + return 0; +} + + + +/* Block list support routines. */ + +struct grub_fs_block +{ + grub_disk_addr_t offset; + unsigned long length; +}; + +static grub_err_t +grub_fs_blocklist_open (grub_file_t file, const char *name) +{ + char *p = (char *) name; + unsigned num = 0; + unsigned i; + grub_disk_t disk = file->device->disk; + struct grub_fs_block *blocks; + + /* First, count the number of blocks. */ + do + { + num++; + p = grub_strchr (p, ','); + if (p) + p++; + } + while (p); + + /* Allocate a block list. */ + blocks = grub_malloc (sizeof (struct grub_fs_block) * (num + 1)); + if (! blocks) + return 0; + + file->size = 0; + p = (char *) name; + for (i = 0; i < num; i++) + { + if (*p != '+') + { + blocks[i].offset = grub_strtoull (p, &p, 0); + if (grub_errno != GRUB_ERR_NONE || *p != '+') + { + grub_error (GRUB_ERR_BAD_FILENAME, + "invalid file name `%s'", name); + goto fail; + } + } + else + blocks[i].offset = 0; + + p++; + blocks[i].length = grub_strtoul (p, &p, 0); + if (grub_errno != GRUB_ERR_NONE + || blocks[i].length == 0 + || (*p && *p != ',' && ! grub_isspace (*p))) + { + grub_error (GRUB_ERR_BAD_FILENAME, + "invalid file name `%s'", name); + goto fail; + } + + if (disk->total_sectors < blocks[i].offset + blocks[i].length) + { + grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors"); + goto fail; + } + + file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS); + p++; + } + + blocks[i].length = 0; + file->data = blocks; + + return GRUB_ERR_NONE; + + fail: + grub_free (blocks); + return grub_errno; +} + +static grub_ssize_t +grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_fs_block *p; + grub_disk_addr_t sector; + grub_off_t offset; + grub_ssize_t ret = 0; + + if (len > file->size - file->offset) + len = file->size - file->offset; + + sector = (file->offset >> GRUB_DISK_SECTOR_BITS); + offset = (file->offset & (GRUB_DISK_SECTOR_SIZE - 1)); + for (p = file->data; p->length && len > 0; p++) + { + if (sector < p->length) + { + grub_size_t size; + + size = len; + if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS) > p->length - sector) + size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset; + + if (grub_disk_read (file->device->disk, p->offset + sector, offset, + size, buf) != GRUB_ERR_NONE) + return -1; + + ret += size; + len -= size; + sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS); + offset = ((size + offset) & (GRUB_DISK_SECTOR_SIZE - 1)); + } + else + sector -= p->length; + } + + return ret; +} + +struct grub_fs grub_fs_blocklist = + { + .name = "blocklist", + .dir = 0, + .open = grub_fs_blocklist_open, + .read = grub_fs_blocklist_read, + .close = 0, + .next = 0 + }; diff --git a/kern/generic/millisleep.c b/kern/generic/millisleep.c new file mode 100644 index 0000000..20d883d --- /dev/null +++ b/kern/generic/millisleep.c @@ -0,0 +1,39 @@ +/* millisleep.c - generic millisleep function. + * The generic implementation of these functions can be used for architectures + * or platforms that do not have a more specialized implementation. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +void +grub_millisleep (grub_uint32_t ms) +{ + grub_uint64_t start; + + start = grub_get_time_ms (); + + /* Instead of setting an end time and looping while the current time is + less than that, comparing the elapsed sleep time with the desired sleep + time handles the (unlikely!) case that the timer would wrap around + during the sleep. */ + + while (grub_get_time_ms () - start < ms) + grub_cpu_idle (); +} diff --git a/kern/generic/rtc_get_time_ms.c b/kern/generic/rtc_get_time_ms.c new file mode 100644 index 0000000..74979e7 --- /dev/null +++ b/kern/generic/rtc_get_time_ms.c @@ -0,0 +1,37 @@ +/* rtc_get_time_ms.c - get_time_ms implementation using platform RTC. + * The generic implementation of these functions can be used for architectures + * or platforms that do not have a more specialized implementation. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +/* Calculate the time in milliseconds since the epoch based on the RTC. */ +grub_uint64_t +grub_rtc_get_time_ms (void) +{ + /* By dimensional analysis: + + 1000 ms N rtc ticks 1 s + ------- * ----------- * ----------- = 1000*N/T ms + 1 s 1 T rtc ticks + */ + grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc (); + return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0); +} diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c new file mode 100644 index 0000000..9978d4a --- /dev/null +++ b/kern/i386/coreboot/init.c @@ -0,0 +1,156 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 + +extern char _start[]; +extern char _end[]; + +grub_addr_t grub_os_area_addr; +grub_size_t grub_os_area_size; + +grub_uint32_t +grub_get_rtc (void) +{ + grub_fatal ("grub_get_rtc() is not implemented.\n"); +} + +/* Stop the floppy drive from spinning, so that other software is + jumped to with a known state. */ +void +grub_stop_floppy (void) +{ + grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT); +} + +void +grub_exit (void) +{ + grub_fatal ("grub_exit() is not implemented.\n"); +} + +void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} + +void +grub_machine_init (void) +{ + /* Initialize the console as early as possible. */ + grub_vga_text_init (); + grub_at_keyboard_init (); + + auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { +#if GRUB_CPU_SIZEOF_VOID_P == 4 + /* Restrict ourselves to 32-bit memory space. */ + if (addr > ULONG_MAX) + { + grub_upper_mem = ULONG_MAX; + return 0; + } + if (addr + size > ULONG_MAX) + size = ULONG_MAX - addr; +#endif + + grub_upper_mem = grub_max (grub_upper_mem, addr + size); + + if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + return 0; + + /* Avoid the lower memory. */ + if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE) + { + if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE) + return 0; + else + { + size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr; + addr = GRUB_MEMORY_MACHINE_LOWER_SIZE; + } + } + + if (addr == GRUB_MEMORY_MACHINE_UPPER_START + || (addr >= GRUB_MEMORY_MACHINE_LOWER_SIZE + && addr <= GRUB_MEMORY_MACHINE_UPPER_START + && (addr + size > GRUB_MEMORY_MACHINE_UPPER_START))) + { + grub_size_t quarter = size >> 2; + + grub_os_area_addr = addr; + grub_os_area_size = size - quarter; + grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size), + quarter); + } + else + grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size); + + return 0; + } + + grub_machine_mmap_init (); + grub_machine_mmap_iterate (heap_init); + + /* This variable indicates size, not offset. */ + grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START; + + grub_tsc_init (); +} + +void +grub_machine_set_prefix (void) +{ + /* Initialize the prefix. */ + grub_env_set ("prefix", grub_prefix); +} + +void +grub_machine_fini (void) +{ + grub_at_keyboard_fini (); + grub_vga_text_fini (); +} + +/* Return the end of the core image. */ +grub_addr_t +grub_arch_modules_addr (void) +{ + return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); +} diff --git a/kern/i386/coreboot/mmap.c b/kern/i386/coreboot/mmap.c new file mode 100644 index 0000000..b15369e --- /dev/null +++ b/kern/i386/coreboot/mmap.c @@ -0,0 +1,97 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t)) +{ + grub_linuxbios_table_header_t table_header; + grub_linuxbios_table_item_t table_item; + + auto int check_signature (grub_linuxbios_table_header_t); + int check_signature (grub_linuxbios_table_header_t tbl_header) + { + if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) + return 1; + + return 0; + } + + /* Assuming table_header is aligned to its size (8 bytes). */ + + for (table_header = (grub_linuxbios_table_header_t) 0x500; + table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++) + if (check_signature (table_header)) + goto signature_found; + + for (table_header = (grub_linuxbios_table_header_t) 0xf0000; + table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++) + if (check_signature (table_header)) + goto signature_found; + + grub_fatal ("Could not find coreboot table\n"); + +signature_found: + + table_item = + (grub_linuxbios_table_item_t) ((long) table_header + + (long) table_header->size); + for (; table_item->size; + table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size)) + if (hook (table_item)) + return 1; + + return 0; +} + +void +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + mem_region_t mem_region; + + auto int iterate_linuxbios_table (grub_linuxbios_table_item_t); + int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item) + { + if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY) + return 0; + + mem_region = + (mem_region_t) ((long) table_item + + sizeof (struct grub_linuxbios_table_item)); + while ((long) mem_region < (long) table_item + (long) table_item->size) + { + if (hook (mem_region->addr, mem_region->size, + /* Multiboot mmaps match with the coreboot mmap definition. + Therefore, we can just pass type through. */ + mem_region->type)) + return 1; + + mem_region++; + } + + return 0; + } + + grub_linuxbios_table_iterate (iterate_linuxbios_table); + + return 0; +} diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S new file mode 100644 index 0000000..835978b --- /dev/null +++ b/kern/i386/coreboot/startup.S @@ -0,0 +1,99 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define ASM_FILE 1 + +#include +#include +#include +#include +#include +#include + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + + .file "startup.S" + .text + .globl start, _start +start: +_start: + jmp codestart + + /* + * This is a special data area at a fixed offset from the beginning. + */ + + . = EXT_C(start) + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + GRUB_KERNEL_CPU_DATA_END + +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long MULTIBOOT_MEMORY_INFO + /* checksum */ + .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO + +codestart: + cmpl $MULTIBOOT_MAGIC2, %eax + jne 0f + movl %ebx, EXT_C(startup_multiboot_info) +0: + + /* initialize the stack */ + movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp + + /* jump to the main body of C code */ + jmp EXT_C(grub_main) + +/* + * This call is special... it never returns... in fact it should simply + * hang at this point! + */ +FUNCTION(grub_stop) + hlt + jmp EXT_C(grub_stop) + +/* + * prot_to_real and associated structures (but NOT real_to_prot, that is + * only needed for BIOS gates). + */ +#include "../realmode.S" + +/* + * Routines needed by Linux and Multiboot loaders. + */ +#include "../loader.S" diff --git a/kern/i386/dl.c b/kern/i386/dl.c new file mode 100644 index 0000000..e9e43e5 --- /dev/null +++ b/kern/i386/dl.c @@ -0,0 +1,111 @@ +/* dl-386.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS32 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_386) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + Elf32_Shdr *s; + Elf32_Sym *symtab; + Elf32_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf32_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf32_Rel *rel, *max; + + for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf32_Word *addr; + Elf32_Sym *sym; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf32_Sym *) ((char *) symtab + + entsize * ELF32_R_SYM (rel->r_info)); + + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_386_32: + *addr += sym->st_value; + break; + + case R_386_PC32: + *addr += (sym->st_value - (Elf32_Word) seg->addr + - rel->r_offset); + break; + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/i386/efi/init.c b/kern/i386/efi/init.c new file mode 100644 index 0000000..e1950d7 --- /dev/null +++ b/kern/i386/efi/init.c @@ -0,0 +1,53 @@ +/* init.c - initialize an x86-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +grub_machine_init (void) +{ + grub_efi_init (); + grub_tsc_init (); +} + +void +grub_machine_fini (void) +{ + grub_efi_fini (); +} + +void +grub_machine_set_prefix (void) +{ + grub_efi_set_prefix (); +} + +void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} diff --git a/kern/i386/efi/startup.S b/kern/i386/efi/startup.S new file mode 100644 index 0000000..4709b3f --- /dev/null +++ b/kern/i386/efi/startup.S @@ -0,0 +1,64 @@ +/* startup.S - bootstrap GRUB itself */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + + .file "startup.S" + .text + .globl start, _start +start: +_start: + jmp codestart + + /* + * Compatibility version number + * + * These MUST be at byte offset 6 and 7 of the executable + * DO NOT MOVE !!! + */ + . = EXT_C(start) + 0x6 + .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = EXT_C(start) + 0x8 + +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + 0x50 + +codestart: + /* + * EFI_SYSTEM_TABLE * and EFI_HANDLE are passed on the stack. + */ + movl 4(%esp), %eax + movl %eax, EXT_C(grub_efi_image_handle) + movl 8(%esp), %eax + movl %eax, EXT_C(grub_efi_system_table) + call EXT_C(grub_main) + ret diff --git a/kern/i386/halt.c b/kern/i386/halt.c new file mode 100644 index 0000000..3895ae1 --- /dev/null +++ b/kern/i386/halt.c @@ -0,0 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +const char bochs_shutdown[] = "Shutdown"; + +void +grub_halt (void) +{ + int i; + + /* Disable interrupts. */ + __asm__ __volatile__ ("cli"); + + /* Bochs, QEMU, etc. */ + for (i = 0; i < sizeof (bochs_shutdown) - 1; i++) + grub_outb (bochs_shutdown[i], 0x8900); + + grub_printf ("GRUB doesn't know how to halt this machine yet!\n"); + + /* In order to return we'd have to check what the previous status of IF + flag was. But user most likely doesn't want to return anyway ... */ + grub_stop (); +} diff --git a/kern/i386/ieee1275/init.c b/kern/i386/ieee1275/init.c new file mode 100644 index 0000000..066373e --- /dev/null +++ b/kern/i386/ieee1275/init.c @@ -0,0 +1,32 @@ +/* init.c -- Initialize GRUB on Open Firmware. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +void +grub_stop_floppy (void) +{ +} + +void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S new file mode 100644 index 0000000..db6ce1e --- /dev/null +++ b/kern/i386/ieee1275/startup.S @@ -0,0 +1,80 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define ASM_FILE 1 + +#include +#include +#include +#include +#include +#include + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + + .file "startup.S" + .text + .globl start, _start + +start: +_start: + jmp codestart + + /* + * This is a special data area at a fixed offset from the beginning. + */ + + . = EXT_C(start) + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + GRUB_KERNEL_CPU_DATA_END + +codestart: + movl %eax, EXT_C(grub_ieee1275_entry_fn) + jmp EXT_C(grub_main) + +/* + * This call is special... it never returns... in fact it should simply + * hang at this point! + */ +FUNCTION(grub_stop) + hlt + jmp EXT_C(grub_stop) + +/* + * prot_to_real and associated structures (but NOT real_to_prot, that is + * only needed for BIOS gates). + */ +#include "../realmode.S" + +/* + * Routines needed by Linux and Multiboot loaders. + */ +#include "../loader.S" diff --git a/kern/i386/loader.S b/kern/i386/loader.S new file mode 100644 index 0000000..cacbbea --- /dev/null +++ b/kern/i386/loader.S @@ -0,0 +1,243 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +/* + * This is the area for all of the special variables. + */ + + .p2align 2 /* force 4-byte alignment */ + +/* + * void grub_linux_boot_zimage (void) + */ +VARIABLE(grub_linux_prot_size) + .long 0 +VARIABLE(grub_linux_tmp_addr) + .long 0 +VARIABLE(grub_linux_real_addr) + .long 0 +VARIABLE(grub_linux_is_bzimage) + .long 0 + +FUNCTION(grub_linux_boot) + /* Must be done before zImage copy. */ + call EXT_C(grub_dl_unload_all) + + movl EXT_C(grub_linux_is_bzimage), %ebx + test %ebx, %ebx + jne bzimage + + /* copy the kernel */ + movl EXT_C(grub_linux_prot_size), %ecx + addl $3, %ecx + shrl $2, %ecx + movl $GRUB_LINUX_BZIMAGE_ADDR, %esi + movl $GRUB_LINUX_ZIMAGE_ADDR, %edi + cld + rep + movsl + +bzimage: + movl EXT_C(grub_linux_real_addr), %ebx + + /* copy the real mode code */ + movl EXT_C(grub_linux_tmp_addr), %esi + movl %ebx, %edi + movl $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx + cld + rep + movsb + + /* change %ebx to the segment address */ + shrl $4, %ebx + movl %ebx, %eax + addl $0x20, %eax + movw %ax, linux_setup_seg + + /* XXX new stack pointer in safe area for calling functions */ + movl $0x4000, %esp + call EXT_C(grub_stop_floppy) + + /* final setup for linux boot */ + call prot_to_real + .code16 + + cli + movw %bx, %ss + movw $GRUB_LINUX_SETUP_STACK, %sp + + movw %bx, %ds + movw %bx, %es + movw %bx, %fs + movw %bx, %gs + + /* ljmp */ + .byte 0xea + .word 0 +linux_setup_seg: + .word 0 + .code32 + + +/* + * This starts the multiboot kernel. + */ + +VARIABLE(grub_multiboot_payload_size) + .long 0 +VARIABLE(grub_multiboot_payload_orig) + .long 0 +VARIABLE(grub_multiboot_payload_dest) + .long 0 +VARIABLE(grub_multiboot_payload_entry_offset) + .long 0 + +/* + * The relocators below understand the following parameters: + * ecx: Size of the block to be copied. + * esi: Where to copy from (always lowest address, even if we're relocating + * backwards). + * edi: Where to copy to (likewise). + * edx: Offset of the entry point (relative to the beginning of the block). + */ +VARIABLE(grub_multiboot_forward_relocator) + /* Add entry offset. */ + addl %edi, %edx + + /* Forward copy. */ + cld + rep + movsb + + jmp *%edx +VARIABLE(grub_multiboot_forward_relocator_end) + +VARIABLE(grub_multiboot_backward_relocator) + /* Add entry offset (before %edi is mangled). */ + addl %edi, %edx + + /* Backward movsb is implicitly off-by-one. compensate that. */ + decl %esi + decl %edi + + /* Backward copy. */ + std + addl %ecx, %esi + addl %ecx, %edi + rep + movsb + + jmp *%edx +VARIABLE(grub_multiboot_backward_relocator_end) + +FUNCTION(grub_multiboot_real_boot) + /* Push the entry address on the stack. */ + pushl %eax + /* Move the address of the multiboot information structure to ebx. */ + movl %edx,%ebx + + /* Unload all modules and stop the floppy driver. */ + call EXT_C(grub_dl_unload_all) + call EXT_C(grub_stop_floppy) + + /* Interrupts should be disabled. */ + cli + + /* Where do we copy what from. */ + movl EXT_C(grub_multiboot_payload_size), %ecx + movl EXT_C(grub_multiboot_payload_orig), %esi + movl EXT_C(grub_multiboot_payload_dest), %edi + movl EXT_C(grub_multiboot_payload_entry_offset), %edx + + /* Move the magic value into eax. */ + movl $MULTIBOOT_MAGIC2, %eax + + /* Jump to the relocator. */ + popl %ebp + jmp *%ebp + +/* + * This starts the multiboot 2 kernel. + */ + +FUNCTION(grub_multiboot2_real_boot) + /* Push the entry address on the stack. */ + pushl %eax + /* Move the address of the multiboot information structure to ebx. */ + movl %edx,%ebx + + /* Unload all modules and stop the floppy driver. */ + call EXT_C(grub_dl_unload_all) + call EXT_C(grub_stop_floppy) + + /* Interrupts should be disabled. */ + cli + + /* Move the magic value into eax and jump to the kernel. */ + movl $MULTIBOOT2_BOOTLOADER_MAGIC,%eax + popl %ecx + jmp *%ecx + +/* + * Use cdecl calling convention for *BSD kernels. + */ + +FUNCTION(grub_unix_real_boot) + + call EXT_C(grub_dl_unload_all) + call EXT_C(grub_stop_floppy) + + /* Interrupts should be disabled. */ + cli + + /* Discard `grub_unix_real_boot' return address. */ + popl %eax + + /* Fetch `entry' address ... */ + popl %eax + + /* + * ... and put our return address in its place. The kernel will + * ignore it, but it expects %esp to point to it. + */ + call *%eax diff --git a/kern/i386/multiboot_mmap.c b/kern/i386/multiboot_mmap.c new file mode 100644 index 0000000..8331bd5 --- /dev/null +++ b/kern/i386/multiboot_mmap.c @@ -0,0 +1,86 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +grub_size_t grub_lower_mem, grub_upper_mem; + +/* A pointer to the MBI in its initial location. */ +struct grub_multiboot_info *startup_multiboot_info; + +/* The MBI has to be copied to our BSS so that it won't be + overwritten. This is its final location. */ +static struct grub_multiboot_info kern_multiboot_info; + +/* Unfortunately we can't use heap at this point. But 32 looks like a sane + limit (used by memtest86). */ +static grub_uint8_t mmap_entries[sizeof (struct grub_multiboot_mmap_entry) * 32]; + +void +grub_machine_mmap_init () +{ + if (! startup_multiboot_info) + grub_fatal ("Must be loaded using Multiboot specification (is this an old version of coreboot?)"); + + /* Move MBI to a safe place. */ + grub_memmove (&kern_multiboot_info, startup_multiboot_info, sizeof (struct grub_multiboot_info)); + + if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEM_MAP) == 0) + grub_fatal ("Missing Multiboot memory information"); + + /* Move the memory map to a safe place. */ + if (kern_multiboot_info.mmap_length > sizeof (mmap_entries)) + { + grub_printf ("WARNING: Memory map size exceeds limit; it will be truncated\n"); + kern_multiboot_info.mmap_length = sizeof (mmap_entries); + } + grub_memmove (mmap_entries, (void *) kern_multiboot_info.mmap_addr, kern_multiboot_info.mmap_length); + kern_multiboot_info.mmap_addr = (grub_uint32_t) mmap_entries; + + if ((kern_multiboot_info.flags & MULTIBOOT_INFO_MEMORY) == 0) + { + grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE; + grub_upper_mem = 0; + } + else + { + grub_lower_mem = kern_multiboot_info.mem_lower * 1024; + grub_upper_mem = kern_multiboot_info.mem_upper * 1024; + } +} + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + struct grub_multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr; + + while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length) + { + if (hook (entry->addr, entry->len, entry->type)) + break; + + entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size)); + } + + return 0; +} diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c new file mode 100644 index 0000000..c604e93 --- /dev/null +++ b/kern/i386/pc/init.c @@ -0,0 +1,229 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mem_region +{ + grub_addr_t addr; + grub_size_t size; +}; + +#define MAX_REGIONS 32 + +static struct mem_region mem_regions[MAX_REGIONS]; +static int num_regions; + +grub_addr_t grub_os_area_addr; +grub_size_t grub_os_area_size; +grub_size_t grub_lower_mem, grub_upper_mem; + +void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} + +static char * +make_install_device (void) +{ + /* XXX: This should be enough. */ + char dev[100]; + + if (grub_prefix[0] != '(') + { + /* If the root drive is not set explicitly, assume that it is identical + to the boot drive. */ + if (grub_root_drive == 0xFF) + grub_root_drive = grub_boot_drive; + + grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f', + grub_root_drive & 0x7f); + + if (grub_install_dos_part >= 0) + grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1); + + if (grub_install_bsd_part >= 0) + grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a'); + + grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix); + grub_strcpy (grub_prefix, dev); + } + + return grub_prefix; +} + +/* Add a memory region. */ +static void +add_mem_region (grub_addr_t addr, grub_size_t size) +{ + if (num_regions == MAX_REGIONS) + /* Ignore. */ + return; + + mem_regions[num_regions].addr = addr; + mem_regions[num_regions].size = size; + num_regions++; +} + +/* Compact memory regions. */ +static void +compact_mem_regions (void) +{ + int i, j; + + /* Sort them. */ + for (i = 0; i < num_regions - 1; i++) + for (j = i + 1; j < num_regions; j++) + if (mem_regions[i].addr > mem_regions[j].addr) + { + struct mem_region tmp = mem_regions[i]; + mem_regions[i] = mem_regions[j]; + mem_regions[j] = tmp; + } + + /* Merge overlaps. */ + for (i = 0; i < num_regions - 1; i++) + if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr) + { + j = i + 1; + + if (mem_regions[i].addr + mem_regions[i].size + < mem_regions[j].addr + mem_regions[j].size) + mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size + - mem_regions[i].addr); + + grub_memmove (mem_regions + j, mem_regions + j + 1, + (num_regions - j - 1) * sizeof (struct mem_region)); + i--; + num_regions--; + } +} + +void +grub_machine_init (void) +{ + int i; + + /* Initialize the console as early as possible. */ + grub_console_init (); + + grub_lower_mem = grub_get_memsize (0) << 10; + + /* Sanity check. */ + if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END) + grub_fatal ("too small memory"); + +#if 0 + /* Turn on Gate A20 to access >1MB. */ + grub_gate_a20 (1); +#endif + + /* Add the lower memory into free memory. */ + if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END) + add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END, + grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END); + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + /* Avoid the lower memory. */ + if (addr < 0x100000) + { + if (size <= 0x100000 - addr) + return 0; + + size -= 0x100000 - addr; + addr = 0x100000; + } + + /* Ignore >4GB. */ + if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE) + { + grub_size_t len; + + len = (grub_size_t) ((addr + size > 0xFFFFFFFF) + ? 0xFFFFFFFF - addr + : size); + add_mem_region (addr, len); + } + + return 0; + } + + grub_machine_mmap_iterate (hook); + + compact_mem_regions (); + + /* Add the memory regions to free memory, except for the region starting + from 1MB. This region is partially used for loading OS images. + For now, 1/4 of this is added to free memory. */ + for (i = 0; i < num_regions; i++) + if (mem_regions[i].addr == 0x100000) + { + grub_size_t quarter = mem_regions[i].size >> 2; + + grub_upper_mem = mem_regions[i].size; + grub_os_area_addr = mem_regions[i].addr; + grub_os_area_size = mem_regions[i].size - quarter; + grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size), + quarter); + } + else + grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size); + + if (! grub_os_area_addr) + grub_fatal ("no upper memory"); + + grub_tsc_init (); +} + +void +grub_machine_set_prefix (void) +{ + /* Initialize the prefix. */ + grub_env_set ("prefix", make_install_device ()); +} + +void +grub_machine_fini (void) +{ + grub_console_fini (); +} + +/* Return the end of the core image. */ +grub_addr_t +grub_arch_modules_addr (void) +{ + return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE); +} diff --git a/kern/i386/pc/lzma_decode.S b/kern/i386/pc/lzma_decode.S new file mode 100644 index 0000000..a5a8684 --- /dev/null +++ b/kern/i386/pc/lzma_decode.S @@ -0,0 +1,677 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define FIXED_PROPS + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +#define kNumTopBits 24 +#define kTopValue (1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + + +#if 0 + +DbgOut: + pushf + pushl %ebp + pushl %edi + pushl %esi + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + + call _DebugPrint + + popl %eax + popl %ebx + popl %ecx + popl %edx + popl %esi + popl %edi + popl %ebp + popf + + ret + + +/* + * int LzmaDecodeProperties(CLzmaProperties *propsRes, + * const unsigned char *propsData, + * int size); + */ + +_LzmaDecodePropertiesA: + movb (%edx), %dl + + xorl %ecx, %ecx +1: + cmpb $45, %dl + jb 2f + incl %ecx + subb $45, %dl + jmp 1b +2: + movl %ecx, 8(%eax) /* pb */ + xorl %ecx, %ecx +1: + cmpb $9, %dl + jb 2f + incl %ecx + subb $9, %dl +2: + movl %ecx, 4(%eax) /* lp */ + movb %dl, %cl + movl %ecx, (%eax) /* lc */ + +#endif + +#ifndef ASM_FILE + xorl %eax, %eax +#endif + ret + +#define out_size 8(%ebp) + +#define now_pos -4(%ebp) +#define prev_byte -8(%ebp) +#define range -12(%ebp) +#define code -16(%ebp) +#define state -20(%ebp) +#define rep0 -24(%ebp) +#define rep1 -28(%ebp) +#define rep2 -32(%ebp) +#define rep3 -36(%ebp) + +#ifdef FIXED_PROPS + +#define FIXED_LC 3 +#define FIXED_LP 0 +#define FIXED_PB 2 + +#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1) +#define LIT_POS_MASK ((1 << (FIXED_LP)) - 1) + +#define LOCAL_SIZE 36 + +#else + +#define lc (%ebx) +#define lp 4(%ebx) +#define pb 8(%ebx) +#define probs 12(%ebx) + +#define pos_state_mask -40(%ebp) +#define lit_pos_mask -44(%ebp) + +#define LOCAL_SIZE 44 + +#endif + +RangeDecoderBitDecode: +#ifdef FIXED_PROPS + leal (%ebx, %eax, 4), %eax +#else + shll $2, %eax + addl probs, %eax +#endif + + movl %eax, %ecx + movl (%ecx), %eax + + movl range, %edx + shrl $kNumBitModelTotalBits, %edx + mull %edx + + cmpl code, %eax + jbe 1f + + movl %eax, range + movl $kBitModelTotal, %edx + subl (%ecx), %edx + shrl $kNumMoveBits, %edx + addl %edx, (%ecx) + clc +3: + pushf + cmpl $kTopValue, range + jnc 2f + shll $8, code + lodsb + movb %al, code + shll $8, range +2: + popf + ret +1: + subl %eax, range + subl %eax, code + movl (%ecx), %edx + shrl $kNumMoveBits, %edx + subl %edx, (%ecx) + stc + jmp 3b + +RangeDecoderBitTreeDecode: +RangeDecoderReverseBitTreeDecode: + movzbl %cl, %ecx + xorl %edx, %edx + pushl %edx + incl %edx + pushl %edx + +1: + pushl %eax + pushl %ecx + pushl %edx + + addl %edx, %eax + call RangeDecoderBitDecode + + popl %edx + popl %ecx + + jnc 2f + movl 4(%esp), %eax + orl %eax, 8(%esp) + stc + +2: + adcl %edx, %edx + popl %eax + + shll $1, (%esp) + loop 1b + + popl %ecx + subl %ecx, %edx /* RangeDecoderBitTreeDecode */ + popl %ecx /* RangeDecoderReverseBitTreeDecode */ + ret + +LzmaLenDecode: + pushl %eax + addl $LenChoice, %eax + call RangeDecoderBitDecode + popl %eax + jc 1f + pushl $0 + movb $kLenNumLowBits, %cl + addl $LenLow, %eax +2: + movl 12(%esp), %edx + shll %cl, %edx + addl %edx, %eax +3: + + call RangeDecoderBitTreeDecode + popl %eax + addl %eax, %edx + ret + +1: + pushl %eax + addl $LenChoice2, %eax + call RangeDecoderBitDecode + popl %eax + jc 1f + pushl $kLenNumLowSymbols + movb $kLenNumMidBits, %cl + addl $LenMid, %eax + jmp 2b + +1: + pushl $(kLenNumLowSymbols + kLenNumMidSymbols) + addl $LenHigh, %eax + movb $kLenNumHighBits, %cl + jmp 3b + +WriteByte: + movb %al, prev_byte + stosb + incl now_pos + ret + +/* + * int LzmaDecode(CLzmaDecoderState *vs, + * const unsigned char *inStream, + * unsigned char *outStream, + * SizeT outSize); + */ + +_LzmaDecodeA: + + pushl %ebp + movl %esp, %ebp + subl $LOCAL_SIZE, %esp + +#ifndef ASM_FILE + pushl %esi + pushl %edi + pushl %ebx + + movl %eax, %ebx + movl %edx, %esi + pushl %ecx +#else + pushl %edi +#endif + + cld + +#ifdef FIXED_PROPS + movl %ebx, %edi + movl $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx +#else + movl $LZMA_LIT_SIZE, %eax + movb lc, %cl + addb lp, %cl + shll %cl, %eax + addl $Literal, %eax + movl %eax, %ecx + movl probs, %edi +#endif + + movl $(kBitModelTotal >> 1), %eax + + rep + stosl + + popl %edi + + xorl %eax, %eax + movl %eax, now_pos + movl %eax, prev_byte + movl %eax, state + + incl %eax + movl %eax, rep0 + movl %eax, rep1 + movl %eax, rep2 + movl %eax, rep3 + +#ifndef FIXED_PROPS + movl %eax, %edx + movb pb, %cl + shll %cl, %edx + decl %edx + movl %edx, pos_state_mask + + movl %eax, %edx + movb lp, %cl + shll %cl, %edx + decl %edx + movl %edx, lit_pos_mask; +#endif + + /* RangeDecoderInit */ + negl %eax + movl %eax, range + + incl %eax + movb $5, %cl + +1: + shll $8, %eax + lodsb + loop 1b + + movl %eax, code + +lzma_decode_loop: + movl now_pos, %eax + cmpl out_size, %eax + + jb 1f + +#ifndef ASM_FILE + xorl %eax, %eax + + popl %ebx + popl %edi + popl %esi +#endif + + movl %ebp, %esp + popl %ebp + ret + +1: +#ifdef FIXED_PROPS + andl $POS_STATE_MASK, %eax +#else + andl pos_state_mask, %eax +#endif + pushl %eax /* posState */ + movl state, %edx + shll $kNumPosBitsMax, %edx + addl %edx, %eax + pushl %eax /* (state << kNumPosBitsMax) + posState */ + + call RangeDecoderBitDecode + jc 1f + + movl now_pos, %eax + +#ifdef FIXED_PROPS + andl $LIT_POS_MASK, %eax + shll $FIXED_LC, %eax + movl prev_byte, %edx + shrl $(8 - FIXED_LC), %edx +#else + andl lit_pos_mask, %eax + movb lc, %cl + shll %cl, %eax + negb %cl + addb $8, %cl + movl prev_byte, %edx + shrl %cl, %edx +#endif + + addl %edx, %eax + movl $LZMA_LIT_SIZE, %edx + mull %edx + addl $Literal, %eax + pushl %eax + + incl %edx /* edx = 1 */ + + movl rep0, %eax + negl %eax + pushl (%edi, %eax) /* matchByte */ + + cmpb $kNumLitStates, state + jb 5f + + /* LzmaLiteralDecodeMatch */ + +3: + cmpl $0x100, %edx + jae 4f + + xorl %eax, %eax + shlb $1, (%esp) + adcl %eax, %eax + + pushl %eax + pushl %edx + + shll $8, %eax + leal 0x100(%edx, %eax), %eax + addl 12(%esp), %eax + call RangeDecoderBitDecode + + setc %al + popl %edx + adcl %edx, %edx + + popl %ecx + cmpb %cl, %al + jz 3b + +5: + + /* LzmaLiteralDecode */ + + cmpl $0x100, %edx + jae 4f + + pushl %edx + movl %edx, %eax + addl 8(%esp), %eax + call RangeDecoderBitDecode + popl %edx + adcl %edx, %edx + jmp 5b + +4: + addl $16, %esp + + movb %dl, %al + call WriteByte + + movb state, %al + cmpb $4, %al + jae 2f + xorb %al, %al + jmp 3f +2: + subb $3, %al + cmpb $7, %al + jb 3f + subb $3, %al +3: + movb %al, state + jmp lzma_decode_loop + +1: + movl state, %eax + addl $IsRep, %eax + call RangeDecoderBitDecode + jnc 1f + + movl state, %eax + addl $IsRepG0, %eax + call RangeDecoderBitDecode + jc 10f + + movl (%esp), %eax + addl $IsRep0Long, %eax + call RangeDecoderBitDecode + jc 20f + + cmpb $7, state + movb $9, state + jb 100f + addb $2, state +100: + + movl $1, %ecx + +3: + movl rep0, %edx + negl %edx + +4: + movb (%edi, %edx), %al + call WriteByte + loop 4b + + popl %eax + popl %eax + jmp lzma_decode_loop + +10: + movl state, %eax + addl $IsRepG1, %eax + call RangeDecoderBitDecode + movl rep1, %edx + jnc 100f + + movl state, %eax + addl $IsRepG2, %eax + call RangeDecoderBitDecode + movl rep2, %edx + jnc 1000f + movl rep2, %edx + xchgl rep3, %edx +1000: + pushl rep1 + popl rep2 +100: + xchg rep0, %edx + movl %edx, rep1 +20: + + movl $RepLenCoder, %eax + call LzmaLenDecode + + cmpb $7, state + movb $8, state + jb 100f + addb $3, state +100: + jmp 2f + +1: + movl rep0, %eax + xchgl rep1, %eax + xchgl rep2, %eax + movl %eax, rep3 + + cmpb $7, state + movb $7, state + jb 10f + addb $3, state +10: + + movl $LenCoder, %eax + call LzmaLenDecode + pushl %edx + + movl $(kNumLenToPosStates - 1), %eax + cmpl %eax, %edx + jbe 100f + movl %eax, %edx +100: + movb $kNumPosSlotBits, %cl + shll %cl, %edx + leal PosSlot(%edx), %eax + call RangeDecoderBitTreeDecode + + movl %edx, rep0 + cmpl $kStartPosModelIndex, %edx + jb 100f + + movl %edx, %ecx + shrl $1, %ecx + decl %ecx + + movzbl %dl, %eax + andb $1, %al + orb $2, %al + shll %cl, %eax + movl %eax, rep0 + + cmpl $kEndPosModelIndex, %edx + jae 200f + movl rep0, %eax + addl $(SpecPos - 1), %eax + subl %edx, %eax + jmp 300f +200: + + subb $kNumAlignBits, %cl + + /* RangeDecoderDecodeDirectBits */ + xorl %edx, %edx + +1000: + shrl $1, range + shll $1, %edx + + movl range, %eax + cmpl %eax, code + jb 2000f + subl %eax, code + orb $1, %dl +2000: + + cmpl $kTopValue, %eax + jae 3000f + shll $8, range + shll $8, code + lodsb + movb %al, code + +3000: + loop 1000b + + movb $kNumAlignBits, %cl + shll %cl, %edx + addl %edx, rep0 + + movl $Align, %eax + +300: + call RangeDecoderReverseBitTreeDecode + addl %ecx, rep0 + +100: + incl rep0 + popl %edx + +2: + + addl $kMatchMinLen, %edx + movl %edx, %ecx + + jmp 3b diff --git a/kern/i386/pc/lzo1x.S b/kern/i386/pc/lzo1x.S new file mode 100644 index 0000000..e942e98 --- /dev/null +++ b/kern/i386/pc/lzo1x.S @@ -0,0 +1,315 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + * Copyright (C) 2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was stolen from the files enter.sh, leave.sh, lzo1x_d.sh, + * lzo1x_f.s and lzo_asm.h in LZO version 1.08, and was heavily modified + * to adapt it to GRUB's requirement. + * + * See , for more information + * about LZO. + */ + +#define INP 4+16(%esp) +#define INS 8+16(%esp) +#define OUTP 12+16(%esp) +#define NN 3 +#define N_3 %ebp +#define N_255 $255 +#define LODSB movb (%esi), %al ; incl %esi +#define NOTL_3(r) xorl N_3, r +#define MOVSL(r1,r2,x) movl (r1), x ; addl $4, r1 ; movl x, (r2) ; addl $4, r2 +#define COPYL_C(r1,r2,x,rc) 9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b +#define COPYL(r1,r2,x) COPYL_C(r1,r2,x,%ecx) + +lzo1x_decompress: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + cld + + movl INP, %esi + movl OUTP, %edi + movl $3, %ebp + + + xorl %eax, %eax + xorl %ebx, %ebx /* high bits 9-32 stay 0 */ + lodsb + cmpb $17, %al + jbe .L01 + subb $17-NN, %al + jmp .LFLR + + +/*********************************************************************** +// literal run +************************************************************************/ + +0: addl N_255, %eax +1: movb (%esi), %bl + incl %esi + orb %bl, %bl + jz 0b + leal 18+NN(%eax,%ebx), %eax + jmp 3f + + +.L00: + LODSB +.L01: + cmpb $16, %al + jae .LMATCH + + /* a literal run */ + orb %al, %al + jz 1b + addl $3+NN, %eax +3: +.LFLR: + movl %eax, %ecx + NOTL_3(%eax) + shrl $2, %ecx + andl N_3, %eax + COPYL(%esi,%edi,%edx) + subl %eax, %esi + subl %eax, %edi + + LODSB + cmpb $16, %al + jae .LMATCH + + +/*********************************************************************** +// R1 +************************************************************************/ + + shrl $2, %eax + movb (%esi), %bl + leal -0x801(%edi), %edx + leal (%eax,%ebx,4), %eax + incl %esi + subl %eax, %edx + movl (%edx), %ecx + movl %ecx, (%edi) + addl N_3, %edi + jmp .LMDONE + + +/*********************************************************************** +// M2 +************************************************************************/ + +.LMATCH: + cmpb $64, %al + jb .LM3MATCH + + /* a M2 match */ + movl %eax, %ecx + shrl $2, %eax + leal -1(%edi), %edx + andl $7, %eax + movb (%esi), %bl + shrl $5, %ecx + leal (%eax,%ebx,8), %eax + incl %esi + subl %eax, %edx + + addl $1+3, %ecx + + cmpl N_3, %eax + jae .LCOPYLONG + jmp .LCOPYBYTE + + +/*********************************************************************** +// M3 +************************************************************************/ + +0: addl N_255, %eax +1: movb (%esi), %bl + incl %esi + orb %bl, %bl + jz 0b + leal 33+NN(%eax,%ebx), %ecx + xorl %eax, %eax + jmp 3f + + +.LM3MATCH: + cmpb $32, %al + jb .LM4MATCH + + /* a M3 match */ + andl $31, %eax + jz 1b + lea 2+NN(%eax), %ecx +3: + movw (%esi), %ax + leal -1(%edi), %edx + shrl $2, %eax + addl $2, %esi + subl %eax, %edx + + cmpl N_3, %eax + jb .LCOPYBYTE + + +/*********************************************************************** +// copy match +************************************************************************/ + +.LCOPYLONG: /* copy match using longwords */ + leal -3(%edi,%ecx), %eax + shrl $2, %ecx + COPYL(%edx,%edi,%ebx) + movl %eax, %edi + xorl %ebx, %ebx + +.LMDONE: + movb -2(%esi), %al + andl N_3, %eax + jz .L00 +.LFLR3: + movl (%esi), %edx + addl %eax, %esi + movl %edx, (%edi) + addl %eax, %edi + + LODSB + jmp .LMATCH + + +.LCOPYBYTE: /* copy match using bytes */ + xchgl %edx,%esi + subl N_3,%ecx + + rep + movsb + movl %edx, %esi + jmp .LMDONE + + +/*********************************************************************** +// M4 +************************************************************************/ + +0: addl N_255, %ecx +1: movb (%esi), %bl + incl %esi + orb %bl, %bl + jz 0b + leal 9+NN(%ebx,%ecx), %ecx + jmp 3f + + +.LM4MATCH: + cmpb $16, %al + jb .LM1MATCH + + /* a M4 match */ + movl %eax, %ecx + andl $8, %eax + shll $13, %eax /* save in bit 16 */ + andl $7, %ecx + jz 1b + addl $2+NN, %ecx +3: + movw (%esi), %ax + addl $2, %esi + leal -0x4000(%edi), %edx + shrl $2, %eax + jz .LEOF + subl %eax, %edx + jmp .LCOPYLONG + + +/*********************************************************************** +// M1 +************************************************************************/ + +.LM1MATCH: + /* a M1 match */ + shrl $2, %eax + movb (%esi), %bl + leal -1(%edi), %edx + leal (%eax,%ebx,4), %eax + incl %esi + subl %eax, %edx + + movb (%edx), %al /* we must use this because edx can be edi-1 */ + movb %al, (%edi) + movb 1(%edx), %bl + movb %bl, 1(%edi) + addl $2, %edi + jmp .LMDONE + + +/*********************************************************************** +// +************************************************************************/ + +.LEOF: +/**** xorl %eax,%eax eax=0 from above */ + + cmpl $3+NN, %ecx /* ecx must be 3/6 */ + setnz %al + + /* check compressed size */ + movl INP, %edx + addl INS, %edx + cmpl %edx, %esi /* check compressed size */ + ja .L_input_overrun + jb .L_input_not_consumed + +.L_leave: + negl %eax + jnz 1f + + subl OUTP, %edi /* write back the uncompressed size */ + movl %edi, %eax + +1: popl %ebx + popl %esi + popl %edi + popl %ebp + ret + +.L_input_not_consumed: + movl $8, %eax /* LZO_E_INPUT_NOT_CONSUMED */ + jmp .L_leave + +.L_input_overrun: + movl $4, %eax /* LZO_E_INPUT_OVERRUN */ + jmp .L_leave + +#undef INP +#undef INS +#undef OUTP +#undef NN +#undef NN +#undef N_3 +#undef N_255 +#undef LODSB +#undef NOTL_3 +#undef MOVSL +#undef COPYL_C +#undef COPYL diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c new file mode 100644 index 0000000..d289c73 --- /dev/null +++ b/kern/i386/pc/mmap.c @@ -0,0 +1,63 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + grub_uint32_t cont; + struct grub_machine_mmap_entry *entry + = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Check if grub_get_mmap_entry works. */ + cont = grub_get_mmap_entry (entry, 0); + + if (entry->size) + do + { + if (hook (entry->addr, entry->len, + /* Multiboot mmaps have been defined to match with the E820 definition. + Therefore, we can just pass type through. */ + entry->type)) + break; + + if (! cont) + break; + + cont = grub_get_mmap_entry (entry, cont); + } + while (entry->size); + else + { + grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); + + if (eisa_mmap) + { + if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0) + hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE); + } + else + hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE); + } + + return 0; +} diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S new file mode 100644 index 0000000..18f61d8 --- /dev/null +++ b/kern/i386/pc/startup.S @@ -0,0 +1,2156 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ABS(x) ((x) - EXT_C(start) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) + + .file "startup.S" + + .text + + /* Tell GAS to generate 16-bit instructions so that this code works + in real mode. */ + .code16 + + .globl start, _start +start: +_start: + /* + * Guarantee that "main" is loaded at 0x0:0x8200. + */ + ljmp $0, $ABS(codestart) + + /* + * Compatibility version number + * + * These MUST be at byte offset 6 and 7 of the executable + * DO NOT MOVE !!! + */ + . = EXT_C(start) + 0x6 + .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = EXT_C(start) + 0x8 + +VARIABLE(grub_total_module_size) + .long 0 +VARIABLE(grub_kernel_image_size) + .long 0 +VARIABLE(grub_compressed_size) + .long 0 +VARIABLE(grub_install_dos_part) + .long 0xFFFFFFFF +VARIABLE(grub_install_bsd_part) + .long 0xFFFFFFFF +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + GRUB_KERNEL_MACHINE_DATA_END + +/* + * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). + * This uses the a.out kludge to load raw binary to the area starting at 1MB, + * and relocates itself after loaded. + */ + .p2align 2 /* force 4-byte alignment */ +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long (1 << 16) + /* checksum */ + .long -0x1BADB002 - (1 << 16) + /* header addr */ + .long multiboot_header - _start + 0x100000 + 0x200 + /* load addr */ + .long 0x100000 + /* load end addr */ + .long 0 + /* bss end addr */ + .long 0 + /* entry addr */ + .long multiboot_entry - _start + 0x100000 + 0x200 + +multiboot_entry: + .code32 + /* obtain the boot device */ + movl 12(%ebx), %edx + + /* relocate the code */ + movl $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx + addl EXT_C(grub_compressed_size) - _start + 0x100000 + 0x200, %ecx + movl $0x100000, %esi + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi + cld + rep + movsb + /* jump to the real address */ + movl $multiboot_trampoline, %eax + jmp *%eax + +multiboot_trampoline: + /* fill the boot information */ + movl %edx, %eax + shrl $8, %eax + xorl %ebx, %ebx + cmpb $0xFF, %ah + je 1f + movb %ah, %bl + movl %ebx, EXT_C(grub_install_dos_part) +1: + cmpb $0xFF, %al + je 2f + movb %al, %bl + movl %ebx, EXT_C(grub_install_bsd_part) +2: + shrl $24, %edx + movb $0xFF, %dh + /* enter the usual booting */ + call prot_to_real + .code16 + +/* the real mode code continues... */ +codestart: + cli /* we're not safe here! */ + + /* set up %ds, %ss, and %es */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw %ax, %es + + /* set up the real mode/BIOS stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp + movl %ebp, %esp + + sti /* we're safe again */ + + /* save boot and root drive references */ + ADDR32 movb %dl, EXT_C(grub_boot_drive) + ADDR32 movb %dh, EXT_C(grub_root_drive) + + /* reset disk system (%ah = 0) */ + int $0x13 + + /* transition to protected mode */ + DATA32 call real_to_prot + + /* The ".code32" directive takes GAS out of 16-bit mode. */ + .code32 + + incl %eax + call EXT_C(grub_gate_a20) + +#if defined(ENABLE_LZO) + /* decompress the compressed part and put the result at 1MB */ + movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %esi + movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %edi + + pushl %esi + pushl EXT_C(grub_compressed_size) + pushl %edi + call lzo1x_decompress + addl $12, %esp + + movl %eax, %ecx + cld +#elif defined(ENABLE_LZMA) + movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi + movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi + pushl %edi + pushl %esi + movl EXT_C(grub_kernel_image_size), %ecx + addl EXT_C(grub_total_module_size), %ecx + subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx + pushl %ecx + leal (%edi, %ecx), %ebx + call _LzmaDecodeA + /* _LzmaDecodeA clears DF, so no need to run cld */ + popl %ecx + popl %edi + popl %esi +#endif + + /* copy back the decompressed part (except the modules) */ + subl EXT_C(grub_total_module_size), %ecx + rep + movsb + +#if 0 + /* copy modules before cleaning out the bss */ + movl EXT_C(grub_total_module_size), %ecx + movl EXT_C(grub_kernel_image_size), %esi + addl %ecx, %esi + addl $START_SYMBOL, %esi + decl %esi + movl $END_SYMBOL, %edi + addl %ecx, %edi + decl %edi + std + rep + movsb +#endif + + /* clean out the bss */ + movl $BSS_START_SYMBOL, %edi + + /* compute the bss length */ + movl $END_SYMBOL, %ecx + subl %edi, %ecx + + /* clean out */ + xorl %eax, %eax + cld + rep + stosb + + /* + * Call the start of main body of C code. + */ + call EXT_C(grub_main) + +#include "../realmode.S" + +/* + * This is the area for all of the special variables. + */ + + .p2align 2 /* force 4-byte alignment */ + +VARIABLE(grub_boot_drive) + .long 0 + +VARIABLE(grub_root_drive) + .long 0 + +VARIABLE(grub_start_addr) + .long START_SYMBOL + +VARIABLE(grub_end_addr) + .long END_SYMBOL + +VARIABLE(grub_apm_bios_info) + .word 0 /* version */ + .word 0 /* cseg */ + .long 0 /* offset */ + .word 0 /* cseg_16 */ + .word 0 /* dseg_16 */ + .word 0 /* cseg_len */ + .word 0 /* cseg_16_len */ + .word 0 /* dseg_16_len */ + + .p2align 2 /* force 4-byte alignment */ + +/* + * These next two routines, "real_to_prot" and "prot_to_real" are structured + * in a very specific way. Be very careful when changing them. + * + * NOTE: Use of either one messes up %eax and %ebp. + */ + +real_to_prot: + .code16 + cli + + /* load the GDT register */ + DATA32 ADDR32 lgdt %cs:gdtdesc + + /* turn on protected mode */ + movl %cr0, %eax + orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + movl %eax, %cr0 + + /* jump to relocation, flush prefetch queue, and reload %cs */ + DATA32 ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg + + .code32 +protcseg: + /* reload other segment registers */ + movw $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* put the return address in a known safe location */ + movl (%esp), %eax + movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK + + /* get protected mode stack */ + movl protstack, %eax + movl %eax, %esp + movl %eax, %ebp + + /* get return address onto the right stack */ + movl GRUB_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, (%esp) + + /* zero %eax */ + xorl %eax, %eax + + /* return on the old (or initialized) stack! */ + ret + +/* + * grub_gate_a20(int on) + * + * Gate address-line 20 for high memory. + * + * This routine is probably overconservative in what it does, but so what? + * + * It also eats any keystrokes in the keyboard buffer. :-( + */ + +FUNCTION(grub_gate_a20) + movl %eax, %edx + +gate_a20_test_current_state: + /* first of all, test if already in a good state */ + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_bios + ret + +gate_a20_try_bios: + /* second, try a BIOS call */ + pushl %ebp + call prot_to_real + + .code16 + movw $0x2400, %ax + testb %dl, %dl + jz 1f + incw %ax +1: int $0x15 + + DATA32 call real_to_prot + .code32 + + popl %ebp + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_system_control_port_a + ret + +gate_a20_try_system_control_port_a: + /* + * In macbook, the keyboard test would hang the machine, so we move + * this forward. + */ + /* fourth, try the system control port A */ + inb $0x92 + andb $(~0x03), %al + testb %dl, %dl + jz 6f + orb $0x02, %al +6: outb $0x92 + + /* When turning off Gate A20, do not check the state strictly, + because a failure is not fatal usually, and Gate A20 is always + on some modern machines. */ + testb %dl, %dl + jz 7f + call gate_a20_check_state + cmpb %al, %dl + jnz gate_a20_try_keyboard_controller +7: ret + +gate_a20_flush_keyboard_buffer: + inb $0x64 + andb $0x02, %al + jnz gate_a20_flush_keyboard_buffer +2: + inb $0x64 + andb $0x01, %al + jz 3f + inb $0x60 + jmp 2b +3: + ret + +gate_a20_try_keyboard_controller: + /* third, try the keyboard controller */ + call gate_a20_flush_keyboard_buffer + + movb $0xd1, %al + outb $0x64 +4: + inb $0x64 + andb $0x02, %al + jnz 4b + + movb $0xdd, %al + testb %dl, %dl + jz 5f + orb $0x02, %al +5: outb $0x60 + call gate_a20_flush_keyboard_buffer + + /* output a dummy command (USB keyboard hack) */ + movb $0xff, %al + outb $0x64 + call gate_a20_flush_keyboard_buffer + + call gate_a20_check_state + cmpb %al, %dl + /* everything failed, so restart from the beginning */ + jnz gate_a20_try_bios + ret + +gate_a20_check_state: + /* iterate the checking for a while */ + movl $100, %ecx +1: + call 3f + cmpb %al, %dl + jz 2f + loop 1b +2: + ret +3: + pushl %ebx + pushl %ecx + xorl %eax, %eax + /* compare the byte at 0x8000 with that at 0x108000 */ + movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx + pushl %ebx + /* save the original byte in CL */ + movb (%ebx), %cl + /* store the value at 0x108000 in AL */ + addl $0x100000, %ebx + movb (%ebx), %al + /* try to set one less value at 0x8000 */ + popl %ebx + movb %al, %ch + decb %ch + movb %ch, (%ebx) + /* serialize */ + outb %al, $0x80 + outb %al, $0x80 + /* obtain the value at 0x108000 in CH */ + pushl %ebx + addl $0x100000, %ebx + movb (%ebx), %ch + /* this result is 1 if A20 is on or 0 if it is off */ + subb %ch, %al + xorb $1, %al + /* restore the original */ + popl %ebx + movb %cl, (%ebx) + popl %ecx + popl %ebx + ret + +#if defined(ENABLE_LZO) +#include "lzo1x.S" +#elif defined(ENABLE_LZMA) +#include "lzma_decode.S" +#endif + +/* + * The code beyond this point is compressed. Assert that the uncompressed + * code fits GRUB_KERNEL_MACHINE_RAW_SIZE. + */ + . = EXT_C(start) + GRUB_KERNEL_MACHINE_RAW_SIZE + +/* + * This call is special... it never returns... in fact it should simply + * hang at this point! + */ + +FUNCTION(grub_stop) + call prot_to_real + + /* + * This next part is sort of evil. It takes advantage of the + * byte ordering on the x86 to work in either 16-bit or 32-bit + * mode, so think about it before changing it. + */ + +FUNCTION(grub_hard_stop) + hlt + jmp EXT_C(grub_hard_stop) + + +/* + * grub_stop_floppy() + * + * Stop the floppy drive from spinning, so that other software is + * jumped to with a known state. + */ +FUNCTION(grub_stop_floppy) + movw $0x3F2, %dx + xorb %al, %al + outb %al, %dx + ret + +/* + * grub_exit() + * + * Exit the system. + */ +FUNCTION(grub_exit) + call prot_to_real + .code16 + /* Tell the BIOS a boot failure. If this does not work, reboot. */ + int $0x18 + jmp cold_reboot + .code32 + +/* + * grub_reboot() + * + * Reboot the system. At the moment, rely on BIOS. + */ +FUNCTION(grub_reboot) + call prot_to_real + .code16 +cold_reboot: + /* cold boot */ + movw $0x0472, %di + movw %ax, (%di) + ljmp $0xFFFF, $0x0000 + .code32 + +/* + * grub_halt(int no_apm) + * + * Halt the system, using APM if possible. If NO_APM is true, don't use + * APM even if it is available. + */ +FUNCTION(grub_halt) + /* see if zero */ + testl %eax, %eax + jnz EXT_C(grub_stop) + + call prot_to_real + .code16 + + /* detect APM */ + movw $0x5300, %ax + xorw %bx, %bx + int $0x15 + jc EXT_C(grub_hard_stop) + /* don't check %bx for buggy BIOSes... */ + + /* disconnect APM first */ + movw $0x5304, %ax + xorw %bx, %bx + int $0x15 + + /* connect APM */ + movw $0x5301, %ax + xorw %bx, %bx + int $0x15 + jc EXT_C(grub_hard_stop) + + /* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */ + movw $0x530E, %ax + xorw %bx, %bx + movw $0x0101, %cx + int $0x15 + jc EXT_C(grub_hard_stop) + + /* set the power state to off */ + movw $0x5307, %ax + movw $1, %bx + movw $3, %cx + int $0x15 + + /* shouldn't reach here */ + jmp EXT_C(grub_hard_stop) + .code32 + + +/* + * void grub_chainloader_real_boot (int drive, void *part_addr) + * + * This starts another boot loader. + */ + +FUNCTION(grub_chainloader_real_boot) + pushl %edx + pushl %eax + + call EXT_C(grub_dl_unload_all) + + /* Turn off Gate A20 */ + xorl %eax, %eax + call EXT_C(grub_gate_a20) + + /* set up to pass boot drive */ + popl %edx + + /* ESI must point to a partition table entry */ + popl %esi + + call prot_to_real + .code16 + ljmp $0, $GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR + .code32 + +#include "../loader.S" + +/* + * int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) + * + * Call IBM/MS INT13 Extensions (int 13 %ah=AH) for DRIVE. DAP + * is passed for disk address packet. If an error occurs, return + * non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_rw_int13_extensions) + pushl %ebp + pushl %esi + + /* compute the address of disk_address_packet */ + movw %cx, %si + xorw %cx, %cx + shrl $4, %ecx /* save the segment to cx */ + + /* ah */ + movb %al, %dh + /* enter real mode */ + call prot_to_real + + .code16 + movb %dh, %ah + movw %cx, %ds + int $0x13 /* do the operation */ + movb %ah, %dl /* save return value */ + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %dl, %al /* return value in %eax */ + + popl %esi + popl %ebp + + ret + +/* + * int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, + * int soff, int nsec, int segment) + * + * Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write + * NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs, + * return non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_rw_standard) + pushl %ebp + movl %esp, %ebp + + pushl %ebx + pushl %edi + pushl %esi + + /* set up CHS information */ + + /* set %ch to low eight bits of cylinder */ + xchgb %cl, %ch + /* set bits 6-7 of %cl to high two bits of cylinder */ + shlb $6, %cl + /* set bits 0-5 of %cl to sector */ + addb 0xc(%ebp), %cl + /* set %dh to head */ + movb 0x8(%ebp), %dh + /* set %ah to AH */ + movb %al, %ah + /* set %al to NSEC */ + movb 0x10(%ebp), %al + /* save %ax in %di */ + movw %ax, %di + /* save SEGMENT in %bx */ + movw 0x14(%ebp), %bx + + /* enter real mode */ + call prot_to_real + + .code16 + movw %bx, %es + xorw %bx, %bx + movw $3, %si /* attempt at least three times */ + +1: + movw %di, %ax + int $0x13 /* do the operation */ + jnc 2f /* check if successful */ + + movb %ah, %bl /* save return value */ + /* if fail, reset the disk system */ + xorw %ax, %ax + int $0x13 + + decw %si + cmpw $0, %si + je 2f + xorb %bl, %bl + jmp 1b /* retry */ +2: + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %esi + popl %edi + popl %ebx + popl %ebp + + ret $(4 * 4) + + +/* + * int grub_biosdisk_check_int13_extensions (int drive) + * + * Check if LBA is supported for DRIVE. If it is supported, then return + * the major version of extensions, otherwise zero. + */ + +FUNCTION(grub_biosdisk_check_int13_extensions) + pushl %ebp + pushl %ebx + + /* drive */ + movb %al, %dl + /* enter real mode */ + call prot_to_real + + .code16 + movb $0x41, %ah + movw $0x55aa, %bx + int $0x13 /* do the operation */ + + /* check the result */ + jc 1f + cmpw $0xaa55, %bx + jne 1f + + movb %ah, %bl /* save the major version into %bl */ + + /* check if AH=0x42 is supported */ + andw $1, %cx + jnz 2f + +1: + xorb %bl, %bl +2: + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %ebx + popl %ebp + + ret + + +/* + * int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp) + * + * Return the cdrom information of DRIVE in CDRP. If an error occurs, + * then return non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions) + movw $0x4B01, %cx + jmp 1f + +/* + * int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp) + * + * Return the geometry of DRIVE in a drive parameters, DRP. If an error + * occurs, then return non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions) + movb $0x48, %ch +1: + pushl %ebp + pushl %ebx + pushl %esi + + /* compute the address of drive parameters */ + movw %dx, %si + andl $0xf, %esi + shrl $4, %edx + movw %dx, %bx /* save the segment into %bx */ + /* drive */ + movb %al, %dl + /* enter real mode */ + call prot_to_real + + .code16 + movw %cx, %ax + movw %bx, %ds + int $0x13 /* do the operation */ + movb %ah, %bl /* save return value in %bl */ + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + movb %bl, %al /* return value in %eax */ + + popl %esi + popl %ebx + popl %ebp + + ret + + +/* + * int grub_biosdisk_get_diskinfo_standard (int drive, + * unsigned long *cylinders, + * unsigned long *heads, + * unsigned long *sectors) + * + * Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an + * error occurs, then return non-zero, otherwise zero. + */ + +FUNCTION(grub_biosdisk_get_diskinfo_standard) + pushl %ebp + pushl %ebx + pushl %edi + + /* push CYLINDERS */ + pushl %edx + /* push HEADS */ + pushl %ecx + /* SECTORS is on the stack */ + + /* drive */ + movb %al, %dl + /* enter real mode */ + call prot_to_real + + .code16 + movb $0x8, %ah + int $0x13 /* do the operation */ + /* check if successful */ + testb %ah, %ah + jnz 1f + /* bogus BIOSes may not return an error number */ + testb $0x3f, %cl /* 0 sectors means no disk */ + jnz 1f /* if non-zero, then succeed */ + /* XXX 0x60 is one of the unused error numbers */ + movb $0x60, %ah +1: + movb %ah, %bl /* save return value in %bl */ + /* back to protected mode */ + DATA32 call real_to_prot + .code32 + + /* pop HEADS */ + popl %edi + movb %dh, %al + incl %eax /* the number of heads is counted from zero */ + movl %eax, (%edi) + + /* pop CYLINDERS */ + popl %edi + movb %ch, %al + movb %cl, %ah + shrb $6, %ah /* the number of cylinders is counted from zero */ + incl %eax + movl %eax, (%edi) + + /* SECTORS */ + movl 0x10(%esp), %edi + andb $0x3f, %cl + movzbl %cl, %eax + movl %eax, (%edi) + + xorl %eax, %eax + movb %bl, %al /* return value in %eax */ + + popl %edi + popl %ebx + popl %ebp + + ret $4 + + +/* + * int grub_biosdisk_get_num_floppies (void) + */ +FUNCTION(grub_biosdisk_get_num_floppies) + pushl %ebp + + xorl %edx, %edx + call prot_to_real + + .code16 + /* reset the disk system first */ + int $0x13 +1: + stc + + /* call GET DISK TYPE */ + movb $0x15, %ah + int $0x13 + + jc 2f + + /* check if this drive exists */ + testb $0x3, %ah + jz 2f + + incb %dl + cmpb $2, %dl + jne 1b +2: + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + popl %ebp + ret + + +/* + * + * grub_get_memsize(i) : return the memory size in KB. i == 0 for conventional + * memory, i == 1 for extended memory + * BIOS call "INT 12H" to get conventional memory size + * BIOS call "INT 15H, AH=88H" to get extended memory size + * Both have the return value in AX. + * + */ + +FUNCTION(grub_get_memsize) + pushl %ebp + + movl %eax, %edx + + call prot_to_real /* enter real mode */ + .code16 + + testl %edx, %edx + jnz xext + + int $0x12 + jmp xdone + +xext: + movb $0x88, %ah + int $0x15 + +xdone: + movw %ax, %dx + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + + popl %ebp + ret + + +/* + * + * grub_get_eisa_mmap() : return packed EISA memory map, lower 16 bits is + * memory between 1M and 16M in 1K parts, upper 16 bits is + * memory above 16M in 64K parts. If error, return zero. + * BIOS call "INT 15H, AH=E801H" to get EISA memory map, + * AX = memory between 1M and 16M in 1K parts. + * BX = memory above 16M in 64K parts. + * + */ + +FUNCTION(grub_get_eisa_mmap) + pushl %ebp + pushl %ebx + + call prot_to_real /* enter real mode */ + .code16 + + movw $0xe801, %ax + int $0x15 + + shll $16, %ebx + movw %ax, %bx + + DATA32 call real_to_prot + .code32 + + cmpb $0x86, %bh + je xnoteisa + + movl %ebx, %eax + +xnoteisa: + popl %ebx + popl %ebp + ret + +/* + * + * grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to + * start), for the Query System Address Map BIOS call. + * + * Sets the first 4-byte int value of "addr" to the size returned by + * the call. If the call fails, sets it to zero. + * + * Returns: new (non-zero) continuation value, 0 if done. + */ + +FUNCTION(grub_get_mmap_entry) + pushl %ebp + pushl %ebx + pushl %edi + pushl %esi + + /* push ADDR */ + pushl %eax + + /* place address (+4) in ES:DI */ + addl $4, %eax + movl %eax, %edi + andl $0xf, %edi + shrl $4, %eax + movl %eax, %esi + + /* set continuation value */ + movl %edx, %ebx + + /* set default maximum buffer size */ + movl $0x14, %ecx + + /* set EDX to 'SMAP' */ + movl $0x534d4150, %edx + + call prot_to_real /* enter real mode */ + .code16 + + movw %si, %es + movl $0xe820, %eax + int $0x15 + + DATA32 jc xnosmap + + cmpl $0x534d4150, %eax + jne xnosmap + + cmpl $0x14, %ecx + jl xnosmap + + cmpl $0x400, %ecx + jg xnosmap + + jmp xsmap + +xnosmap: + xorl %ecx, %ecx + +xsmap: + DATA32 call real_to_prot + .code32 + + /* write length of buffer (zero if error) into ADDR */ + popl %eax + movl %ecx, (%eax) + + /* set return value to continuation */ + movl %ebx, %eax + + popl %esi + popl %edi + popl %ebx + popl %ebp + ret + + +/* + * void grub_console_real_putchar (int c) + * + * Put the character C on the console. Because GRUB wants to write a + * character with an attribute, this implementation is a bit tricky. + * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh + * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, + * save the current position, restore the original position, write the + * character and the attribute, and restore the current position. + * + * The reason why this is so complicated is that there is no easy way to + * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't + * support setting a background attribute. + */ +FUNCTION(grub_console_real_putchar) + movl %eax, %edx + pusha + movb EXT_C(grub_console_cur_color), %bl + + call prot_to_real + .code16 + movb %dl, %al + xorb %bh, %bh + + /* use teletype output if control character */ + cmpb $0x7, %al + je 1f + cmpb $0x8, %al + je 1f + cmpb $0xa, %al + je 1f + cmpb $0xd, %al + je 1f + + /* save the character and the attribute on the stack */ + pushw %ax + pushw %bx + + /* get the current position */ + movb $0x3, %ah + int $0x10 + + /* check the column with the width */ + cmpb $79, %dl + jl 2f + + /* print CR and LF, if next write will exceed the width */ + movw $0x0e0d, %ax + int $0x10 + movb $0x0a, %al + int $0x10 + + /* get the current position */ + movb $0x3, %ah + int $0x10 + +2: + /* restore the character and the attribute */ + popw %bx + popw %ax + + /* write the character with the attribute */ + movb $0x9, %ah + movw $1, %cx + int $0x10 + + /* move the cursor forward */ + incb %dl + movb $0x2, %ah + int $0x10 + + jmp 3f + +1: movw $1, %bx + movb $0xe, %ah + int $0x10 + +3: DATA32 call real_to_prot + .code32 + + popa + ret + + +/* + * int grub_console_getkey (void) + * BIOS call "INT 16H Function 00H" to read character from keyboard + * Call with %ah = 0x0 + * Return: %ah = keyboard scan code + * %al = ASCII character + */ + +/* this table is used in translate_keycode below */ +translation_table: + .word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT + .word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT + .word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP + .word GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN + .word GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME + .word GRUB_CONSOLE_KEY_END, GRUB_TERM_END + .word GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC + .word GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE + .word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE + .word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE + .word 0 + +/* + * translate_keycode translates the key code %dx to an ascii code. + */ + .code16 + +translate_keycode: + pushw %bx + pushw %si + + movw $ABS(translation_table), %si + +1: lodsw + /* check if this is the end */ + testw %ax, %ax + jz 2f + /* load the ascii code into %ax */ + movw %ax, %bx + lodsw + /* check if this matches the key code */ + cmpw %bx, %dx + jne 1b + /* translate %dx, if successful */ + movw %ax, %dx + +2: popw %si + popw %bx + ret + + .code32 + +FUNCTION(grub_console_getkey) + pushl %ebp + + call prot_to_real + .code16 + + /* + * Due to a bug in apple's bootcamp implementation, INT 16/AH = 0 would + * cause the machine to hang at the second keystroke. However, we can + * work around this problem by ensuring the presence of keystroke with + * INT 16/AH = 1 before calling INT 16/AH = 0. + */ + +1: + movb $1, %ah + int $0x16 + jnz 2f + hlt + jmp 1b + +2: + + movb $0, %ah + int $0x16 + + movw %ax, %dx /* real_to_prot uses %eax */ + call translate_keycode + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + + popl %ebp + ret + + +/* + * int grub_console_checkkey (void) + * if there is a character pending, return it; otherwise return -1 + * BIOS call "INT 16H Function 01H" to check whether a character is pending + * Call with %ah = 0x1 + * Return: + * If key waiting to be input: + * %ah = keyboard scan code + * %al = ASCII character + * Zero flag = clear + * else + * Zero flag = set + */ +FUNCTION(grub_console_checkkey) + pushl %ebp + xorl %edx, %edx + + call prot_to_real /* enter real mode */ + .code16 + + movb $0x1, %ah + int $0x16 + + jz notpending + + movw %ax, %dx + DATA32 jmp pending + +notpending: + decl %edx + +pending: + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + + popl %ebp + ret + + +/* + * grub_uint16_t grub_console_getxy (void) + * BIOS call "INT 10H Function 03h" to get cursor position + * Call with %ah = 0x03 + * %bh = page + * Returns %ch = starting scan line + * %cl = ending scan line + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +FUNCTION(grub_console_getxy) + pushl %ebp + pushl %ebx /* save EBX */ + + call prot_to_real + .code16 + + xorb %bh, %bh /* set page to 0 */ + movb $0x3, %ah + int $0x10 /* get cursor position */ + + DATA32 call real_to_prot + .code32 + + movb %dl, %ah + movb %dh, %al + + popl %ebx + popl %ebp + ret + + +/* + * void grub_console_gotoxy(grub_uint8_t x, grub_uint8_t y) + * BIOS call "INT 10H Function 02h" to set cursor position + * Call with %ah = 0x02 + * %bh = page + * %dh = row (0 is top) + * %dl = column (0 is left) + */ + + +FUNCTION(grub_console_gotoxy) + pushl %ebp + pushl %ebx /* save EBX */ + + movb %dl, %dh /* %dh = y */ + movb %al, %dl /* %dl = x */ + + call prot_to_real + .code16 + + xorb %bh, %bh /* set page to 0 */ + movb $0x2, %ah + int $0x10 /* set cursor position */ + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + + +/* + * void grub_console_cls (void) + * BIOS call "INT 10H Function 09h" to write character and attribute + * Call with %ah = 0x09 + * %al = (character) + * %bh = (page number) + * %bl = (attribute) + * %cx = (number of times) + */ + +FUNCTION(grub_console_cls) + pushl %ebp + pushl %ebx /* save EBX */ + + call prot_to_real + .code16 + + /* move the cursor to the beginning */ + movb $0x02, %ah + xorb %bh, %bh + xorw %dx, %dx + int $0x10 + + /* write spaces to the entire screen */ + movw $0x0920, %ax + movw $0x07, %bx + movw $(80 * 25), %cx + int $0x10 + + /* move back the cursor */ + movb $0x02, %ah + int $0x10 + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + + +/* + * void grub_console_setcursor (int on) + * BIOS call "INT 10H Function 01h" to set cursor type + * Call with %ah = 0x01 + * %ch = cursor starting scanline + * %cl = cursor ending scanline + */ + +console_cursor_state: + .byte 1 +console_cursor_shape: + .word 0 + +FUNCTION(grub_console_setcursor) + pushl %ebp + pushl %ebx + + /* push ON */ + pushl %eax + + /* check if the standard cursor shape has already been saved */ + movw console_cursor_shape, %ax + testw %ax, %ax + jne 1f + + call prot_to_real + .code16 + + movb $0x03, %ah + xorb %bh, %bh + int $0x10 + + DATA32 call real_to_prot + .code32 + + movw %cx, console_cursor_shape +1: + /* set %cx to the designated cursor shape */ + movw $0x2000, %cx + popl %eax + testl %eax, %eax + jz 2f + movw console_cursor_shape, %cx +2: + call prot_to_real + .code16 + + movb $0x1, %ah + int $0x10 + + DATA32 call real_to_prot + .code32 + + popl %ebx + popl %ebp + ret + +/* + * grub_getrtsecs() + * if a seconds value can be read, read it and return it (BCD), + * otherwise return 0xFF + * BIOS call "INT 1AH Function 02H" to check whether a character is pending + * Call with %ah = 0x2 + * Return: + * If RT Clock can give correct values + * %ch = hour (BCD) + * %cl = minutes (BCD) + * %dh = seconds (BCD) + * %dl = daylight savings time (00h std, 01h daylight) + * Carry flag = clear + * else + * Carry flag = set + * (this indicates that the clock is updating, or + * that it isn't running) + */ +FUNCTION(grub_getrtsecs) + pushl %ebp + + call prot_to_real /* enter real mode */ + .code16 + + clc + movb $0x2, %ah + int $0x1a + + DATA32 jnc gottime + movb $0xff, %dh + +gottime: + DATA32 call real_to_prot + .code32 + + movb %dh, %al + + popl %ebp + ret + + +/* + * grub_get_rtc() + * return the real time in ticks, of which there are about + * 18-20 per second + */ +FUNCTION(grub_get_rtc) + pushl %ebp + + call prot_to_real /* enter real mode */ + .code16 + + /* %ax is already zero */ + int $0x1a + + DATA32 call real_to_prot + .code32 + + movl %ecx, %eax + shll $16, %eax + movw %dx, %ax + + popl %ebp + ret + + +/* + * unsigned char grub_vga_set_mode (unsigned char mode) + */ +FUNCTION(grub_vga_set_mode) + pushl %ebp + pushl %ebx + movl %eax, %ecx + + call prot_to_real + .code16 + /* get current mode */ + xorw %bx, %bx + movb $0x0f, %ah + int $0x10 + movb %al, %dl + + /* set the new mode */ + movb %cl, %al + xorb %ah, %ah + int $0x10 + + DATA32 call real_to_prot + .code32 + + movb %dl, %al + popl %ebx + popl %ebp + ret + + +/* + * unsigned char *grub_vga_get_font (void) + */ +FUNCTION(grub_vga_get_font) + pushl %ebp + pushl %ebx + + call prot_to_real + .code16 + movw $0x1130, %ax + movb $0x06, %bh + int $0x10 + movw %es, %bx + movw %bp, %dx + DATA32 call real_to_prot + .code32 + + movzwl %bx, %ecx + shll $4, %ecx + movw %dx, %ax + addl %ecx, %eax + + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info) + * + * Register allocations for parameters: + * %eax *controller_info + */ +FUNCTION(grub_vbe_bios_get_controller_info) + pushl %ebp + pushl %edi + pushl %edx + + movw %ax, %di /* Store *controller_info to %edx:%di. */ + xorw %ax, %ax + shrl $4, %eax + mov %eax, %edx /* prot_to_real destroys %eax. */ + + call prot_to_real + .code16 + + pushw %es + + movw %dx, %es /* *controller_info is now on %es:%di. */ + movw $0x4f00, %ax + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + popw %es + + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + andl $0x0FFFF, %eax /* Return value in %eax. */ + + pop %edx + popl %edi + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode, + * struct grub_vbe_mode_info_block *mode_info) + * + * Register allocations for parameters: + * %eax mode + * %edx *mode_info + */ +FUNCTION(grub_vbe_bios_get_mode_info) + pushl %ebp + pushl %edi + + movl %eax, %ecx /* Store mode number to %ecx. */ + + movw %dx, %di /* Store *mode_info to %edx:%di. */ + xorw %dx, %dx + shrl $4, %edx + + call prot_to_real + .code16 + + pushw %es + + movw %dx, %es /* *mode_info is now on %es:%di. */ + movw $0x4f01, %ax + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + popw %es + + DATA32 call real_to_prot + .code32 + + movl %edx, %eax + andl $0x0FFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_set_mode (grub_uint32_t mode, + * struct grub_vbe_crtc_info_block *crtc_info) + * + * Register allocations for parameters: + * %eax mode + * %edx *crtc_info + */ +FUNCTION(grub_vbe_bios_set_mode) + pushl %ebp + pushl %ebx + pushl %edi + + movl %eax, %ebx /* Store mode in %ebx. */ + + movw %dx, %di /* Store *crtc_info to %edx:%di. */ + xorw %dx, %dx + shrl $4, %edx + + call prot_to_real + .code16 + + pushw %es + + movw %dx, %es /* *crtc_info is now on %es:%di. */ + + movw $0x4f02, %ax + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + popw %es + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode) + * + * Register allocations for parameters: + * %eax *mode + */ +FUNCTION(grub_vbe_bios_get_mode) + pushl %ebp + pushl %ebx + pushl %edi + pushl %edx + pushl %eax /* Push *mode to stack. */ + + call prot_to_real + .code16 + + movw $0x4f03, %ax + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + popl %edi /* Pops *mode from stack to %edi. */ + andl $0xFFFF, %ebx + movl %ebx, (%edi) + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edx + popl %edi + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window, + * grub_uint32_t position); + * + * Register allocations for parameters: + * %eax window + * %edx position + */ +FUNCTION(grub_vbe_bios_set_memory_window) + pushl %ebp + pushl %ebx + + movl %eax, %ebx + + call prot_to_real + .code16 + + movw $0x4f05, %ax + andw $0x00ff, %bx /* BL = window, BH = 0, Set memory window. */ + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_get_memory_window (grub_uint32_t window, + * grub_uint32_t *position); + * + * Register allocations for parameters: + * %eax window + * %edx *position + */ +FUNCTION(grub_vbe_bios_get_memory_window) + pushl %ebp + pushl %ebx + pushl %edi + pushl %edx /* Push *position to stack. */ + + movl %eax, %ebx /* Store window in %ebx. */ + + call prot_to_real + .code16 + + movw $0x4f05, %ax + andw $0x00ff, %bx /* BL = window. */ + orw $0x0100, %bx /* BH = 1, Get memory window. */ + int $0x10 + + movw %ax, %bx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + popl %edi /* pops *position from stack to %edi. */ + andl $0xFFFF, %edx + movl %edx, (%edi) /* Return position to caller. */ + + movw %bx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length) + * + * Register allocations for parameters: + * %eax length + */ +FUNCTION(grub_vbe_bios_set_scanline_length) + pushl %ebp + pushl %ebx + pushl %edx + + movl %eax, %ecx /* Store length in %ecx. */ + + call prot_to_real + .code16 + + movw $0x4f06, %ax + movw $0x0002, %bx /* BL = 2, Set Scan Line in Bytes. */ + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edx + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length) + * + * Register allocations for parameters: + * %eax *length + */ +FUNCTION(grub_vbe_bios_get_scanline_length) + pushl %ebp + pushl %ebx + pushl %edi + pushl %edx /* Push *length to stack. */ + + call prot_to_real + .code16 + + movw $0x4f06, %ax + movw $0x0001, %bx /* BL = 1, Get Scan Line Length (in bytes). */ + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + popl %edi /* Pops *length from stack to %edi. */ + andl $0xFFFF, %ebx + movl %ebx, (%edi) /* Return length to caller. */ + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_set_display_start (grub_uint32_t x, + * grub_uint32_t y) + * + * Register allocations for parameters: + * %eax x + * %edx y + */ +FUNCTION(grub_vbe_bios_set_display_start) + pushl %ebp + pushl %ebx + + movl %eax, %ecx /* Store x in %ecx. */ + + call prot_to_real + .code16 + + movw $0x4f07, %ax + movw $0x0080, %bx /* BL = 80h, Set Display Start + during Vertical Retrace. */ + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x, + * grub_uint32_t *y) + * + * Register allocations for parameters: + * %eax *x + * %edx *y + */ +FUNCTION(grub_vbe_bios_get_display_start) + pushl %ebp + pushl %ebx + pushl %edi + pushl %eax /* Push *x to stack. */ + pushl %edx /* Push *y to stack. */ + + call prot_to_real + .code16 + + movw $0x4f07, %ax + movw $0x0001, %bx /* BL = 1, Get Display Start. */ + int $0x10 + + movw %ax, %bx /* real_to_prot destroys %eax. */ + + DATA32 call real_to_prot + .code32 + + popl %edi /* Pops *y from stack to %edi. */ + andl $0xFFFF, %edx + movl %edx, (%edi) /* Return y-position to caller. */ + + popl %edi /* Pops *x from stack to %edi. */ + andl $0xFFFF, %ecx + movl %ecx, (%edi) /* Return x-position to caller. */ + + movw %bx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebx + popl %ebp + ret + +/* + * grub_vbe_status_t grub_vbe_bios_set_palette_data (grub_uint32_t color_count, + * grub_uint32_t start_index, + * struct grub_vbe_palette_data *palette_data) + * + * Register allocations for parameters: + * %eax color_count + * %edx start_index + * %ecx *palette_data + */ +FUNCTION(grub_vbe_bios_set_palette_data) + pushl %ebp + pushl %ebx + pushl %edi + + movl %eax, %ebx /* Store color_count in %ebx. */ + + movw %cx, %di /* Store *palette_data to %ecx:%di. */ + xorw %cx, %cx + shrl $4, %ecx + + call prot_to_real + .code16 + + pushw %es + + movw %cx, %es /* *palette_data is now on %es:%di. */ + movw %bx, %cx /* color_count is now on %cx. */ + + movw $0x4f09, %ax + xorw %bx, %bx /* BL = 0, Set Palette Data. */ + int $0x10 + + movw %ax, %dx /* real_to_prot destroys %eax. */ + + popw %es + + DATA32 call real_to_prot + .code32 + + movw %dx, %ax + andl $0xFFFF, %eax /* Return value in %eax. */ + + popl %edi + popl %ebx + popl %ebp + ret + + +pxe_rm_entry: + .long 0 + +/* + * struct grub_pxenv *grub_pxe_scan (void); + */ +FUNCTION(grub_pxe_scan) + pushl %ebp + pushl %ebx + + xorl %ebx, %ebx + xorl %ecx, %ecx + + call prot_to_real + .code16 + + pushw %es + + movw $0x5650, %ax + int $0x1A + cmpw $0x564E, %ax + jnz 1f + cmpl $0x4E455850, %es:(%bx) /* PXEN(V+) */ + jnz 1f + cmpw $0x201, %es:6(%bx) /* API version */ + jb 1f + lesw %es:0x28(%bx), %bx /* !PXE structure */ + cmpl $0x45585021, %es:(%bx) /* !PXE */ + jnz 1f + movw %es, %cx + jmp 2f +1: + xorw %bx, %bx + xorw %cx, %cx +2: + + popw %es + + DATA32 call real_to_prot + .code32 + + xorl %eax, %eax + leal (%eax, %ecx, 4), %ecx + leal (%ebx, %ecx, 4), %eax /* eax = ecx * 16 + ebx */ + + orl %eax, %eax + jz 1f + + movl 0x10(%eax), %ecx + movl %ecx, pxe_rm_entry + +1: + + popl %ebx + popl %ebp + ret + +/* + * int grub_pxe_call (int func, void* data); + */ +FUNCTION(grub_pxe_call) + pushl %ebp + movl %esp, %ebp + pushl %esi + pushl %edi + pushl %ebx + + movl %eax, %ecx + movl %edx, %eax + andl $0xF, %eax + shrl $4, %edx + shll $16, %edx + addl %eax, %edx + movl pxe_rm_entry, %ebx + + call prot_to_real + .code16 + + pushl %ebx + pushl %edx + pushw %cx + movw %sp, %bx + lcall *%ss:6(%bx) + cld + addw $10, %sp + movw %ax, %cx + + DATA32 call real_to_prot + .code32 + + movzwl %cx, %eax + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret diff --git a/kern/i386/pit.c b/kern/i386/pit.c new file mode 100644 index 0000000..82a17d3 --- /dev/null +++ b/kern/i386/pit.c @@ -0,0 +1,56 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#define TIMER2_REG_CONTROL 0x42 +#define TIMER_REG_COMMAND 0x43 +#define TIMER2_REG_LATCH 0x61 + +#define TIMER2_SELECT 0x80 +#define TIMER_ENABLE_LSB 0x20 +#define TIMER_ENABLE_MSB 0x10 +#define TIMER2_LATCH 0x20 +#define TIMER2_SPEAKER 0x02 +#define TIMER2_GATE 0x01 + +void +grub_pit_wait (grub_uint16_t tics) +{ + /* Disable timer2 gate and speaker. */ + grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE), + TIMER2_REG_LATCH); + + /* Set tics. */ + grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND); + grub_outb (tics & 0xff, TIMER2_REG_CONTROL); + grub_outb (tics >> 8, TIMER2_REG_CONTROL); + + /* Enable timer2 gate, keep speaker disabled. */ + grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE, + TIMER2_REG_LATCH); + + /* Wait. */ + while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00); + + /* Disable timer2 gate and speaker. */ + grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE), + TIMER2_REG_LATCH); +} diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S new file mode 100644 index 0000000..680353e --- /dev/null +++ b/kern/i386/realmode.S @@ -0,0 +1,178 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + +/* + * Note: GRUB is compiled with the options -mrtd and -mregparm=3. + * So the first three arguments are passed in %eax, %edx, and %ecx, + * respectively, and if a function has a fixed number of arguments + * and the number if greater than three, the function must return + * with "ret $N" where N is ((the number of arguments) - 3) * 4. + */ + +/* + * This is the area for all of the special variables. + */ + + .p2align 2 /* force 4-byte alignment */ + +protstack: + .long GRUB_MEMORY_MACHINE_PROT_STACK + +/* + * This is the Global Descriptor Table + * + * An entry, a "Segment Descriptor", looks like this: + * + * 31 24 19 16 7 0 + * ------------------------------------------------------------ + * | | |B| |A| | | |1|0|E|W|A| | + * | BASE 31..24 |G|/|L|V| LIMIT |P|DPL| TYPE | BASE 23:16 | 4 + * | | |D| |L| 19..16| | |1|1|C|R|A| | + * ------------------------------------------------------------ + * | | | + * | BASE 15..0 | LIMIT 15..0 | 0 + * | | | + * ------------------------------------------------------------ + * + * Note the ordering of the data items is reversed from the above + * description. + */ + + .p2align 2 /* force 4-byte alignment */ +gdt: + .word 0, 0 + .byte 0, 0, 0, 0 + + /* -- code segment -- + * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present + * type = 32bit code execute/read, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x9A, 0xCF, 0 + + /* -- data segment -- + * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present + * type = 32 bit data read/write, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0xCF, 0 + + /* -- 16 bit real mode CS -- + * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * type = 16 bit code execute/read only/conforming, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x9E, 0, 0 + + /* -- 16 bit real mode DS -- + * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * type = 16 bit data read/write, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0, 0 + + +/* this is the GDT descriptor */ +gdtdesc: + .word 0x27 /* limit */ + .long gdt /* addr */ + +/* + * These next routine, "prot_to_real" is structured in a very + * specific way. Be very careful when changing it. + * + * NOTE: Use of it messes up %eax and %ebp. + */ + +prot_to_real: + /* just in case, set GDT */ + lgdt gdtdesc + + /* save the protected mode stack */ + movl %esp, %eax + movl %eax, protstack + + /* get the return address */ + movl (%esp), %eax + movl %eax, GRUB_MEMORY_MACHINE_REAL_STACK + + /* set up new stack */ + movl $GRUB_MEMORY_MACHINE_REAL_STACK, %eax + movl %eax, %esp + movl %eax, %ebp + + /* set up segment limits */ + movw $GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* this might be an extra step */ + /* jump to a 16 bit segment */ + ljmp $GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg + +tmpcseg: + .code16 + + /* clear the PE bit of CR0 */ + movl %cr0, %eax + andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax + movl %eax, %cr0 + + /* flush prefetch queue, reload %cs */ + DATA32 ljmp $0, $realcseg + +realcseg: + /* we are in real mode now + * set up the real mode segment registers : DS, SS, ES + */ + /* zero %eax */ + xorl %eax, %eax + + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + /* restore interrupts */ + sti + + /* return on new stack! */ + DATA32 ret + + .code32 diff --git a/kern/i386/reboot.c b/kern/i386/reboot.c new file mode 100644 index 0000000..d2b0060 --- /dev/null +++ b/kern/i386/reboot.c @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +void +grub_reboot (void) +{ + /* Use the keyboard controller to reboot. That's what keyboards were + designed for, isn't it? */ + grub_outb (KEYBOARD_COMMAND_REBOOT, KEYBOARD_REG_STATUS); + + grub_printf ("GRUB doesn't know how to reboot this machine yet!\n"); +} diff --git a/kern/i386/tsc.c b/kern/i386/tsc.c new file mode 100644 index 0000000..4d3f05a --- /dev/null +++ b/kern/i386/tsc.c @@ -0,0 +1,74 @@ +/* kern/i386/tsc.c - x86 TSC time source implementation + * Requires Pentium or better x86 CPU that supports the RDTSC instruction. + * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to + * real time. + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +/* This defines the value TSC had at the epoch (that is, when we calibrated it). */ +static grub_uint64_t tsc_boot_time; + +/* Calibrated TSC rate. (In TSC ticks per millisecond.) */ +static grub_uint64_t tsc_ticks_per_ms; + + +grub_uint64_t +grub_tsc_get_time_ms (void) +{ + return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, 0); +} + + +/* How many RTC ticks to use for calibration loop. (>= 1) */ +#define CALIBRATION_TICKS 2 + +/* Calibrate the TSC based on the RTC. */ +static void +calibrate_tsc (void) +{ + /* First calibrate the TSC rate (relative, not absolute time). */ + grub_uint64_t start_tsc; + grub_uint64_t end_tsc; + + start_tsc = grub_get_tsc (); + grub_pit_wait (0xffff); + end_tsc = grub_get_tsc (); + + tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0); +} + +void +grub_tsc_init (void) +{ + if (grub_cpu_is_tsc_supported ()) + { + tsc_boot_time = grub_get_tsc (); + calibrate_tsc (); + grub_install_get_time_ms (grub_tsc_get_time_ms); + } + else + { + grub_install_get_time_ms (grub_rtc_get_time_ms); + } +} diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c new file mode 100644 index 0000000..b5e2ba6 --- /dev/null +++ b/kern/ieee1275/cmain.c @@ -0,0 +1,167 @@ +/* cmain.c - Startup code for the PowerPC. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +int (*grub_ieee1275_entry_fn) (void *); + +grub_ieee1275_phandle_t grub_ieee1275_chosen; +grub_ieee1275_ihandle_t grub_ieee1275_mmu; + +static grub_uint32_t grub_ieee1275_flags; + + + +int +grub_ieee1275_test_flag (enum grub_ieee1275_flag flag) +{ + return (grub_ieee1275_flags & (1 << flag)); +} + +void +grub_ieee1275_set_flag (enum grub_ieee1275_flag flag) +{ + grub_ieee1275_flags |= (1 << flag); +} + +#define SF "SmartFirmware(tm)" +#define OHW "PPC Open Hack'Ware" + +static void +grub_ieee1275_find_options (void) +{ + grub_ieee1275_phandle_t root; + grub_ieee1275_phandle_t options; + grub_ieee1275_phandle_t openprom; + grub_ieee1275_phandle_t bootrom; + int rc; + grub_uint32_t realmode = 0; + char tmp[32]; + int is_smartfirmware = 0; + int is_olpc = 0; + + grub_ieee1275_finddevice ("/", &root); + grub_ieee1275_finddevice ("/options", &options); + grub_ieee1275_finddevice ("/openprom", &openprom); + + rc = grub_ieee1275_get_integer_property (options, "real-mode?", &realmode, + sizeof realmode, 0); + if (((rc >= 0) && realmode) || (grub_ieee1275_mmu == 0)) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); + + rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright", + tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1)) + is_smartfirmware = 1; + + rc = grub_ieee1275_get_property (root, "architecture", + tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strcmp (tmp, "OLPC")) + is_olpc = 1; + + if (is_smartfirmware) + { + /* Broken in all versions */ + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT); + + /* There are two incompatible ways of checking the version number. Try + both. */ + rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version", + tmp, sizeof (tmp), 0); + if (rc < 0) + rc = grub_ieee1275_get_property (openprom, "firmware-version", + tmp, sizeof (tmp), 0); + if (rc >= 0) + { + /* It is tempting to implement a version parser to set the flags for + e.g. 1.3 and below. However, there's a special situation here. + 3rd party updates which fix the partition bugs are common, and for + some reason their fixes aren't being merged into trunk. So for + example we know that 1.2 and 1.3 are broken, but there's 1.2.99 + and 1.3.99 which are known good (and applying this workaround + would cause breakage). */ + if (!grub_strcmp (tmp, "1.0") + || !grub_strcmp (tmp, "1.1") + || !grub_strcmp (tmp, "1.2") + || !grub_strcmp (tmp, "1.3")) + { + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS); + } + } + } + + if (is_olpc) + { + /* OLPC / XO laptops have three kinds of storage devices: + + - NAND flash. These are accessible via OFW callbacks, but: + - Follow strange semantics, imposed by hardware constraints. + - Its ABI is undocumented, and not stable. + They lack "device_type" property, which conveniently makes GRUB + skip them. + + - USB drives. Not accessible, because OFW shuts down the controller + in order to prevent collisions with applications accessing it + directly. Even worse, attempts to access it will NOT return + control to the caller, so we have to avoid probing them. + + - SD cards. These work fine. + + To avoid brekage, we only need to skip USB probing. However, + since detecting SD cards is more reliable, we do that instead. + */ + + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY); + } + + if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) + { + rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1)) + { + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_ANSI); + } + } +} + +#undef SF +#undef OHW + +void +grub_ieee1275_init (void) +{ + grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + + if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &grub_ieee1275_mmu, + sizeof grub_ieee1275_mmu, 0) < 0) + grub_ieee1275_mmu = 0; + + grub_ieee1275_find_options (); +} diff --git a/kern/ieee1275/ieee1275.c b/kern/ieee1275/ieee1275.c new file mode 100644 index 0000000..aa48e20 --- /dev/null +++ b/kern/ieee1275/ieee1275.c @@ -0,0 +1,602 @@ +/* of.c - Access the Open Firmware client interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_phandle_t) -1) +#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t) 0) +#define IEEE1275_CELL_INVALID ((grub_ieee1275_cell_t) -1) + + + +int +grub_ieee1275_finddevice (char *name, grub_ieee1275_phandle_t *phandlep) +{ + struct find_device_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t device; + grub_ieee1275_phandle_t phandle; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "finddevice", 1, 1); + args.device = (grub_ieee1275_cell_t) name; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *phandlep = args.phandle; + if (args.phandle == IEEE1275_PHANDLE_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_get_property (grub_ieee1275_phandle_t phandle, + const char *property, void *buf, + grub_size_t size, grub_ssize_t *actual) +{ + struct get_property_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t phandle; + grub_ieee1275_cell_t prop; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t buflen; + grub_ieee1275_cell_t size; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "getprop", 4, 1); + args.phandle = phandle; + args.prop = (grub_ieee1275_cell_t) property; + args.buf = (grub_ieee1275_cell_t) buf; + args.buflen = (grub_ieee1275_cell_t) size; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (actual) + *actual = (grub_ssize_t) args.size; + if (args.size == IEEE1275_CELL_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_get_integer_property (grub_ieee1275_phandle_t phandle, + const char *property, grub_uint32_t *buf, + grub_size_t size, grub_ssize_t *actual) +{ + int ret; + ret = grub_ieee1275_get_property (phandle, property, (void *) buf, size, actual); +#ifndef GRUB_CPU_WORDS_BIGENDIAN + /* Integer properties are always in big endian. */ + if (ret == 0) + { + unsigned int i; + size /= sizeof (grub_uint32_t); + for (i = 0; i < size; i++) + buf[i] = grub_be_to_cpu32 (buf[i]); + } +#endif + return ret; +} + +int +grub_ieee1275_next_property (grub_ieee1275_phandle_t phandle, char *prev_prop, + char *prop) +{ + struct get_property_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t phandle; + grub_ieee1275_cell_t prev_prop; + grub_ieee1275_cell_t next_prop; + grub_ieee1275_cell_t flags; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "nextprop", 3, 1); + args.phandle = phandle; + args.prev_prop = (grub_ieee1275_cell_t) prev_prop; + args.next_prop = (grub_ieee1275_cell_t) prop; + args.flags = (grub_ieee1275_cell_t) -1; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + return (int) args.flags; +} + +int +grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle, + const char *prop, grub_ssize_t *length) +{ + struct get_property_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t phandle; + grub_ieee1275_cell_t prop; + grub_ieee1275_cell_t length; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "getproplen", 2, 1); + args.phandle = phandle; + args.prop = (grub_ieee1275_cell_t) prop; + args.length = (grub_ieee1275_cell_t) -1; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *length = args.length; + if (args.length == IEEE1275_CELL_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_instance_to_package (grub_ieee1275_ihandle_t ihandle, + grub_ieee1275_phandle_t *phandlep) +{ + struct instance_to_package_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_phandle_t phandle; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1); + args.ihandle = ihandle; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *phandlep = args.phandle; + if (args.phandle == IEEE1275_PHANDLE_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_package_to_path (grub_ieee1275_phandle_t phandle, + char *path, grub_size_t len, + grub_ssize_t *actual) +{ + struct instance_to_package_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t phandle; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t buflen; + grub_ieee1275_cell_t actual; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "package-to-path", 3, 1); + args.phandle = phandle; + args.buf = (grub_ieee1275_cell_t) path; + args.buflen = (grub_ieee1275_cell_t) len; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (actual) + *actual = args.actual; + if (args.actual == IEEE1275_CELL_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_instance_to_path (grub_ieee1275_ihandle_t ihandle, + char *path, grub_size_t len, + grub_ssize_t *actual) +{ + struct instance_to_path_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t buflen; + grub_ieee1275_cell_t actual; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "instance-to-path", 3, 1); + args.ihandle = ihandle; + args.buf = (grub_ieee1275_cell_t) path; + args.buflen = (grub_ieee1275_cell_t) len; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (actual) + *actual = args.actual; + if (args.actual == IEEE1275_CELL_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer, + grub_size_t len, grub_ssize_t *actualp) +{ + struct write_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t len; + grub_ieee1275_cell_t actual; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "write", 3, 1); + args.ihandle = ihandle; + args.buf = (grub_ieee1275_cell_t) buffer; + args.len = (grub_ieee1275_cell_t) len; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (actualp) + *actualp = args.actual; + return 0; +} + +int +grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer, + grub_size_t len, grub_ssize_t *actualp) +{ + struct write_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t len; + grub_ieee1275_cell_t actual; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "read", 3, 1); + args.ihandle = ihandle; + args.buf = (grub_ieee1275_cell_t) buffer; + args.len = (grub_ieee1275_cell_t) len; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (actualp) + *actualp = args.actual; + return 0; +} + +int +grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, int pos_hi, + int pos_lo, grub_ssize_t *result) +{ + struct write_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t pos_hi; + grub_ieee1275_cell_t pos_lo; + grub_ieee1275_cell_t result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1); + args.ihandle = ihandle; + args.pos_hi = (grub_ieee1275_cell_t) pos_hi; + args.pos_lo = (grub_ieee1275_cell_t) pos_lo; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + if (result) + *result = args.result; + return 0; +} + +int +grub_ieee1275_peer (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result) +{ + struct peer_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t node; + grub_ieee1275_phandle_t result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "peer", 1, 1); + args.node = node; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *result = args.result; + if (args.result == 0) + return -1; + return 0; +} + +int +grub_ieee1275_child (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result) +{ + struct child_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t node; + grub_ieee1275_phandle_t result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "child", 1, 1); + args.node = node; + args.result = IEEE1275_PHANDLE_INVALID; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *result = args.result; + if (args.result == 0) + return -1; + return 0; +} + +int +grub_ieee1275_parent (grub_ieee1275_phandle_t node, + grub_ieee1275_phandle_t *result) +{ + struct parent_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t node; + grub_ieee1275_phandle_t result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "parent", 1, 1); + args.node = node; + args.result = IEEE1275_PHANDLE_INVALID; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *result = args.result; + return 0; +} + +int +grub_ieee1275_interpret (const char *command, grub_ieee1275_cell_t *catch) +{ + struct enter_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t command; + grub_ieee1275_cell_t catch; + } + args; + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) + return -1; + + INIT_IEEE1275_COMMON (&args.common, "interpret", 1, 1); + args.command = (grub_ieee1275_cell_t) command; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (catch) + *catch = args.catch; + return 0; +} + +int +grub_ieee1275_enter (void) +{ + struct enter_args + { + struct grub_ieee1275_common_hdr common; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0); + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + return 0; +} + +void +grub_ieee1275_exit (void) +{ + struct exit_args + { + struct grub_ieee1275_common_hdr common; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "exit", 0, 0); + + IEEE1275_CALL_ENTRY_FN (&args); + for (;;) ; +} + +int +grub_ieee1275_open (const char *path, grub_ieee1275_ihandle_t *result) +{ + struct open_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t path; + grub_ieee1275_ihandle_t result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "open", 1, 1); + args.path = (grub_ieee1275_cell_t) path; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *result = args.result; + if (args.result == IEEE1275_IHANDLE_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle) +{ + struct close_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_ihandle_t ihandle; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "close", 1, 0); + args.ihandle = ihandle; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + return 0; +} + +int +grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align, + grub_addr_t *result) +{ + struct claim_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t addr; + grub_ieee1275_cell_t size; + grub_ieee1275_cell_t align; + grub_ieee1275_cell_t base; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "claim", 3, 1); + args.addr = (grub_ieee1275_cell_t) addr; + args.size = (grub_ieee1275_cell_t) size; + args.align = (grub_ieee1275_cell_t) align; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + if (result) + *result = args.base; + if (args.base == IEEE1275_CELL_INVALID) + return -1; + return 0; +} + +int +grub_ieee1275_release (grub_addr_t addr, grub_size_t size) +{ + struct release_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t addr; + grub_ieee1275_cell_t size; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "release", 2, 0); + args.addr = addr; + args.size = size; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + return 0; +} + +int +grub_ieee1275_set_property (grub_ieee1275_phandle_t phandle, + const char *propname, void *buf, + grub_size_t size, grub_ssize_t *actual) +{ + struct set_property_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_phandle_t phandle; + grub_ieee1275_cell_t propname; + grub_ieee1275_cell_t buf; + grub_ieee1275_cell_t size; + grub_ieee1275_cell_t actual; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "setprop", 4, 1); + args.size = (grub_ieee1275_cell_t) size; + args.buf = (grub_ieee1275_cell_t) buf; + args.propname = (grub_ieee1275_cell_t) propname; + args.phandle = (grub_ieee1275_cell_t) phandle; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *actual = args.actual; + if ((args.actual == IEEE1275_CELL_INVALID) || (args.actual != args.size)) + return -1; + return 0; +} + +int +grub_ieee1275_set_color (grub_ieee1275_ihandle_t ihandle, + int index, int r, int g, int b) +{ + struct set_color_args + { + struct grub_ieee1275_common_hdr common; + char *method; + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_cell_t index; + grub_ieee1275_cell_t b; + grub_ieee1275_cell_t g; + grub_ieee1275_cell_t r; + grub_ieee1275_cell_t catch_result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1); + args.method = "color!"; + args.ihandle = ihandle; + args.index = index; + args.r = r; + args.g = g; + args.b = b; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + return args.catch_result; +} + +int +grub_ieee1275_milliseconds (grub_uint32_t *msecs) +{ + struct milliseconds_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t msecs; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "milliseconds", 0, 1); + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + *msecs = args.msecs; + return 0; +} diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c new file mode 100644 index 0000000..d345ba2 --- /dev/null +++ b/kern/ieee1275/init.c @@ -0,0 +1,291 @@ +/* init.c -- Initialize GRUB on the newworld mac (PPC). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The minimal heap size we can live with. */ +#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) + +/* The maximum heap size we're going to claim */ +#define HEAP_MAX_SIZE (unsigned long) (4 * 1024 * 1024) + +/* If possible, we will avoid claiming heap above this address, because it + seems to cause relocation problems with OSes that link at 4 MiB */ +#define HEAP_MAX_ADDR (unsigned long) (4 * 1024 * 1024) + +extern char _start[]; +extern char _end[]; + +void +grub_exit (void) +{ + grub_ieee1275_exit (); +} + +/* Translate an OF filesystem path (separated by backslashes), into a GRUB + path (separated by forward slashes). */ +static void +grub_translate_ieee1275_path (char *filepath) +{ + char *backslash; + + backslash = grub_strchr (filepath, '\\'); + while (backslash != 0) + { + *backslash = '/'; + backslash = grub_strchr (filepath, '\\'); + } +} + +void +grub_machine_set_prefix (void) +{ + char bootpath[64]; /* XXX check length */ + char *filename; + char *prefix; + + if (grub_env_get ("prefix")) + /* We already set prefix in grub_machine_init(). */ + return; + + if (grub_prefix[0]) + { + grub_env_set ("prefix", grub_prefix); + /* Prefix is hardcoded in the core image. */ + return; + } + + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, + sizeof (bootpath), 0)) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + grub_env_set ("prefix", ""); + return; + } + + /* Transform an OF device path to a GRUB path. */ + + prefix = grub_ieee1275_encode_devname (bootpath); + + filename = grub_ieee1275_get_filename (bootpath); + if (filename) + { + char *newprefix; + char *lastslash = grub_strrchr (filename, '\\'); + + /* Truncate at last directory. */ + if (lastslash) + { + *lastslash = '\0'; + grub_translate_ieee1275_path (filename); + + newprefix = grub_malloc (grub_strlen (prefix) + + grub_strlen (filename)); + grub_sprintf (newprefix, "%s%s", prefix, filename); + grub_free (prefix); + prefix = newprefix; + } + } + + grub_env_set ("prefix", prefix); + + grub_free (filename); + grub_free (prefix); +} + +/* Claim some available memory in the first /memory node. */ +static void grub_claim_heap (void) +{ + unsigned long total = 0; + + auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type); + int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type) + { + if (type != 1) + return 0; + + len -= 1; /* Required for some firmware. */ + + /* Never exceed HEAP_MAX_SIZE */ + if (total + len > HEAP_MAX_SIZE) + len = HEAP_MAX_SIZE - total; + + /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ + if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ + (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ + (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ + len = HEAP_MAX_ADDR - addr; + + /* In theory, firmware should already prevent this from happening by not + listing our own image in /memory/available. The check below is intended + as a safegard in case that doesn't happen. It does, however, not protect + us from corrupting our module area, which extends up to a + yet-undetermined region above _end. */ + if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start)) + { + grub_printf ("Warning: attempt to claim over our own code!\n"); + len = 0; + } + + if (len) + { + /* Claim and use it. */ + if (grub_claimmap (addr, len) < 0) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Failed to claim heap at 0x%llx, len 0x%llx\n", + addr, len); + grub_mm_init_region ((void *) (grub_addr_t) addr, len); + } + + total += len; + if (total >= HEAP_MAX_SIZE) + return 1; + + return 0; + } + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) + heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1); + else + grub_machine_mmap_iterate (heap_init); +} + +#ifdef __i386__ + +grub_uint32_t grub_upper_mem; + +/* We need to call this before grub_claim_memory. */ +static void +grub_get_extended_memory (void) +{ + auto int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type); + int NESTED_FUNC_ATTR find_ext_mem (grub_uint64_t addr, grub_uint64_t len, grub_uint32_t type) + { + if (type == 1 && addr == 0x100000) + { + grub_upper_mem = len; + return 1; + } + + return 0; + } + + grub_machine_mmap_iterate (find_ext_mem); +} + +#endif + +static grub_uint64_t ieee1275_get_time_ms (void); + +void +grub_machine_init (void) +{ + char args[256]; + int actual; + + grub_ieee1275_init (); + + grub_console_init (); +#ifdef __i386__ + grub_get_extended_memory (); +#endif + grub_claim_heap (); + grub_ofdisk_init (); + + /* Process commandline. */ + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", &args, + sizeof args, &actual) == 0 + && actual > 1) + { + int i = 0; + + while (i < actual) + { + char *command = &args[i]; + char *end; + char *val; + + end = grub_strchr (command, ';'); + if (end == 0) + i = actual; /* No more commands after this one. */ + else + { + *end = '\0'; + i += end - command + 1; + while (grub_isspace(args[i])) + i++; + } + + /* Process command. */ + val = grub_strchr (command, '='); + if (val) + { + *val = '\0'; + grub_env_set (command, val + 1); + } + } + } + + grub_install_get_time_ms (ieee1275_get_time_ms); +} + +void +grub_machine_fini (void) +{ + grub_ofdisk_fini (); + grub_console_fini (); +} + +static grub_uint64_t +ieee1275_get_time_ms (void) +{ + grub_uint32_t msecs = 0; + + grub_ieee1275_milliseconds (&msecs); + + return msecs; +} + +grub_uint32_t +grub_get_rtc (void) +{ + return ieee1275_get_time_ms (); +} + +grub_addr_t +grub_arch_modules_addr (void) +{ + return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); +} diff --git a/kern/ieee1275/mmap.c b/kern/ieee1275/mmap.c new file mode 100644 index 0000000..5b30dbb --- /dev/null +++ b/kern/ieee1275/mmap.c @@ -0,0 +1,71 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) +{ + grub_ieee1275_phandle_t root; + grub_ieee1275_phandle_t memory; + grub_uint32_t available[32]; + grub_ssize_t available_size; + grub_uint32_t address_cells = 1; + grub_uint32_t size_cells = 1; + int i; + + /* Determine the format of each entry in `available'. */ + grub_ieee1275_finddevice ("/", &root); + grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells, + sizeof address_cells, 0); + grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells, + sizeof size_cells, 0); + + /* Load `/memory/available'. */ + if (grub_ieee1275_finddevice ("/memory", &memory)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Couldn't find /memory node"); + if (grub_ieee1275_get_integer_property (memory, "available", available, + sizeof available, &available_size)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Couldn't examine /memory/available property"); + + /* Decode each entry and call `hook'. */ + i = 0; + available_size /= sizeof (grub_uint32_t); + while (i < available_size) + { + grub_uint64_t address; + grub_uint64_t size; + + address = available[i++]; + if (address_cells == 2) + address = (address << 32) | available[i++]; + + size = available[i++]; + if (size_cells == 2) + size = (size << 32) | available[i++]; + + if (hook (address, size, GRUB_MACHINE_MEMORY_AVAILABLE)) + break; + } + + return grub_errno; +} diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c new file mode 100644 index 0000000..e88f3b3 --- /dev/null +++ b/kern/ieee1275/openfw.c @@ -0,0 +1,363 @@ +/* openfw.c -- Open firmware support functions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +enum grub_ieee1275_parse_type +{ + GRUB_PARSE_FILENAME, + GRUB_PARSE_PARTITION, +}; + +/* Walk children of 'devpath', calling hook for each. */ +grub_err_t +grub_children_iterate (char *devpath, + int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + grub_ieee1275_phandle_t dev; + grub_ieee1275_phandle_t child; + + if (grub_ieee1275_finddevice (devpath, &dev)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown device"); + + if (grub_ieee1275_child (dev, &child)) + return grub_error (GRUB_ERR_BAD_DEVICE, "Device has no children"); + + do + { + /* XXX: Don't use hardcoded path lengths. */ + char childtype[64]; + char childpath[64]; + char childname[64]; + char fullname[64]; + struct grub_ieee1275_devalias alias; + int actual; + + if (grub_ieee1275_get_property (child, "device_type", &childtype, + sizeof childtype, &actual)) + continue; + + if (grub_ieee1275_package_to_path (child, childpath, sizeof childpath, + &actual)) + continue; + + if (grub_ieee1275_get_property (child, "name", &childname, + sizeof childname, &actual)) + continue; + + grub_sprintf (fullname, "%s/%s", devpath, childname); + + alias.type = childtype; + alias.path = childpath; + alias.name = fullname; + hook (&alias); + } + while (grub_ieee1275_peer (child, &child)); + + return 0; +} + +/* Iterate through all device aliases. This function can be used to + find a device of a specific type. */ +grub_err_t +grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + grub_ieee1275_phandle_t aliases; + char aliasname[32]; + int actual; + struct grub_ieee1275_devalias alias; + + if (grub_ieee1275_finddevice ("/aliases", &aliases)) + return -1; + + /* Find the first property. */ + aliasname[0] = '\0'; + + while (grub_ieee1275_next_property (aliases, aliasname, aliasname)) + { + grub_ieee1275_phandle_t dev; + grub_ssize_t pathlen; + char *devpath; + /* XXX: This should be large enough for any possible case. */ + char devtype[64]; + + grub_dprintf ("devalias", "devalias name = %s\n", aliasname); + + grub_ieee1275_get_property_length (aliases, aliasname, &pathlen); + + /* The property `name' is a special case we should skip. */ + if (!grub_strcmp (aliasname, "name")) + continue; + + devpath = grub_malloc (pathlen); + if (! devpath) + return grub_errno; + + if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen, + &actual)) + { + grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname); + goto nextprop; + } + + if (grub_ieee1275_finddevice (devpath, &dev)) + { + grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath); + goto nextprop; + } + + if (grub_ieee1275_get_property (dev, "device_type", devtype, + sizeof devtype, &actual)) + { + /* NAND device don't have device_type property. */ + devtype[0] = 0; + } + + alias.name = aliasname; + alias.path = devpath; + alias.type = devtype; + hook (&alias); + +nextprop: + grub_free (devpath); + } + + return 0; +} + +/* Call the "map" method of /chosen/mmu. */ +static int +grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size, + grub_uint8_t mode) +{ + struct map_args { + struct grub_ieee1275_common_hdr common; + char *method; + grub_ieee1275_ihandle_t ihandle; + grub_uint32_t mode; + grub_uint32_t size; + grub_uint32_t virt; + grub_uint32_t phys; + int catch_result; + } args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1); + args.method = "map"; + args.ihandle = grub_ieee1275_mmu; + args.phys = phys; + args.virt = virt; + args.size = size; + args.mode = mode; /* Format is WIMG0PP. */ + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + return args.catch_result; +} + +int +grub_claimmap (grub_addr_t addr, grub_size_t size) +{ + if (grub_ieee1275_claim (addr, size, 0, 0)) + return -1; + + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE) + && grub_map (addr, addr, size, 0x00)) + { + grub_printf ("map failed: address 0x%x, size 0x%x\n", addr, size); + grub_ieee1275_release (addr, size); + return -1; + } + + return 0; +} + +/* Get the device arguments of the Open Firmware node name `path'. */ +static char * +grub_ieee1275_get_devargs (const char *path) +{ + char *colon = grub_strchr (path, ':'); + + if (! colon) + return 0; + + return grub_strdup (colon + 1); +} + +/* Get the device path of the Open Firmware node name `path'. */ +static char * +grub_ieee1275_get_devname (const char *path) +{ + char *colon = grub_strchr (path, ':'); + char *newpath = 0; + int pathlen = grub_strlen (path); + auto int match_alias (struct grub_ieee1275_devalias *alias); + + int match_alias (struct grub_ieee1275_devalias *curalias) + { + /* briQ firmware can change capitalization in /chosen/bootpath. */ + if (! grub_strncasecmp (curalias->path, path, pathlen)) + { + newpath = grub_strdup (curalias->name); + return 1; + } + + return 0; + } + + if (colon) + pathlen = (int)(colon - path); + + /* Try to find an alias for this device. */ + grub_devalias_iterate (match_alias); + + if (! newpath) + newpath = grub_strndup (path, pathlen); + + return newpath; +} + +static char * +grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) +{ + char type[64]; /* XXX check size. */ + char *device = grub_ieee1275_get_devname (path); + char *args = grub_ieee1275_get_devargs (path); + char *ret = 0; + grub_ieee1275_phandle_t dev; + + if (!args) + /* Shouldn't happen. */ + return 0; + + /* We need to know what type of device it is in order to parse the full + file path properly. */ + if (grub_ieee1275_finddevice (device, &dev)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device); + goto fail; + } + if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Device %s lacks a device_type property\n", device); + goto fail; + } + + if (!grub_strcmp ("block", type)) + { + /* The syntax of the device arguments is defined in the CHRP and PReP + IEEE1275 bindings: "[partition][,[filename]]". */ + char *comma = grub_strchr (args, ','); + + if (ptype == GRUB_PARSE_FILENAME) + { + if (comma) + { + char *filepath = comma + 1; + + ret = grub_malloc (grub_strlen (filepath) + 1); + /* Make sure filepath has leading backslash. */ + if (filepath[0] != '\\') + grub_sprintf (ret, "\\%s", filepath); + else + grub_strcpy (ret, filepath); + } + } + else if (ptype == GRUB_PARSE_PARTITION) + { + if (!comma) + ret = grub_strdup (args); + else + ret = grub_strndup (args, (grub_size_t)(comma - args)); + } + } + else + { + /* XXX Handle net devices by configuring & registering a grub_net_dev + here, then return its name? + Example path: "net:,,,,,". */ + grub_printf ("Unsupported type %s for device %s\n", type, device); + } + +fail: + grub_free (device); + grub_free (args); + return ret; +} + +char * +grub_ieee1275_get_filename (const char *path) +{ + return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME); +} + +/* Convert a device name from IEEE1275 syntax to GRUB syntax. */ +char * +grub_ieee1275_encode_devname (const char *path) +{ + char *device = grub_ieee1275_get_devname (path); + char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); + char *encoding; + + if (partition) + { + unsigned int partno = grub_strtoul (partition, 0, 0); + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS)) + /* GRUB partition 1 is OF partition 0. */ + partno++; + + /* Assume partno will require less than five bytes to encode. */ + encoding = grub_malloc (grub_strlen (device) + 3 + 5); + grub_sprintf (encoding, "(%s,%d)", device, partno); + } + else + { + encoding = grub_malloc (grub_strlen (device) + 2); + grub_sprintf (encoding, "(%s)", device); + } + + grub_free (partition); + grub_free (device); + + return encoding; +} + +void +grub_reboot (void) +{ + grub_ieee1275_interpret ("reset-all", 0); +} + +void +grub_halt (void) +{ + /* Not standarized. We try both known commands. */ + + grub_ieee1275_interpret ("shut-down", 0); + grub_ieee1275_interpret ("power-off", 0); +} diff --git a/kern/loader.c b/kern/loader.c new file mode 100644 index 0000000..2b67d49 --- /dev/null +++ b/kern/loader.c @@ -0,0 +1,75 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t (*grub_loader_boot_func) (void); +static grub_err_t (*grub_loader_unload_func) (void); +static int grub_loader_noreturn; + +static int grub_loader_loaded; + +int +grub_loader_is_loaded (void) +{ + return grub_loader_loaded; +} + +void +grub_loader_set (grub_err_t (*boot) (void), + grub_err_t (*unload) (void), + int noreturn) +{ + if (grub_loader_loaded && grub_loader_unload_func) + grub_loader_unload_func (); + + grub_loader_boot_func = boot; + grub_loader_unload_func = unload; + grub_loader_noreturn = noreturn; + + grub_loader_loaded = 1; +} + +void +grub_loader_unset(void) +{ + if (grub_loader_loaded && grub_loader_unload_func) + grub_loader_unload_func (); + + grub_loader_boot_func = 0; + grub_loader_unload_func = 0; + + grub_loader_loaded = 0; +} + +grub_err_t +grub_loader_boot (void) +{ + if (! grub_loader_loaded) + return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel"); + + if (grub_loader_noreturn) + grub_machine_fini (); + + return (grub_loader_boot_func) (); +} + diff --git a/kern/main.c b/kern/main.c new file mode 100644 index 0000000..40300b2 --- /dev/null +++ b/kern/main.c @@ -0,0 +1,152 @@ +/* main.c - the kernel main routine */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +grub_module_iterate (int (*hook) (struct grub_module_header *header)) +{ + struct grub_module_info *modinfo; + struct grub_module_header *header; + grub_addr_t modbase; + + modbase = grub_arch_modules_addr (); + modinfo = (struct grub_module_info *) modbase; + + /* Check if there are any modules. */ + if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) + return; + + for (header = (struct grub_module_header *) (modbase + modinfo->offset); + header < (struct grub_module_header *) (modbase + modinfo->size); + header = (struct grub_module_header *) ((char *) header + header->size)) + { + if (hook (header)) + break; + } +} + +/* Load all modules in core. */ +static void +grub_load_modules (void) +{ + auto int hook (struct grub_module_header *); + int hook (struct grub_module_header *header) + { + /* Not an ELF module, skip. */ + if (header->type != OBJ_TYPE_ELF) + return 0; + + if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), + (header->size - sizeof (struct grub_module_header)))) + grub_fatal ("%s", grub_errmsg); + + return 0; + } + + grub_module_iterate (hook); +} + +/* Write hook for the environment variables of root. Remove surrounding + parentheses, if any. */ +static char * +grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + /* XXX Is it better to check the existence of the device? */ + grub_size_t len = grub_strlen (val); + + if (val[0] == '(' && val[len - 1] == ')') + return grub_strndup (val + 1, len - 2); + + return grub_strdup (val); +} + +/* Set the root device according to the dl prefix. */ +static void +grub_set_root_dev (void) +{ + const char *prefix; + + grub_register_variable_hook ("root", 0, grub_env_write_root); + grub_env_export ("root"); + + prefix = grub_env_get ("prefix"); + + if (prefix) + { + char *dev; + + dev = grub_file_get_device_name (prefix); + if (dev) + { + grub_env_set ("root", dev); + grub_free (dev); + } + } +} + +/* Load the normal mode module and execute the normal mode if possible. */ +static void +grub_load_normal_mode (void) +{ + /* Load the module. */ + grub_dl_load ("normal"); + + /* Something went wrong. Print errors here to let user know why we're entering rescue mode. */ + grub_print_error (); +} + +/* The main routine. */ +void +grub_main (void) +{ + /* First of all, initialize the machine. */ + grub_machine_init (); + + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("Welcome to GRUB!\n\n"); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + + /* Load pre-loaded modules and free the space. */ + grub_register_exported_symbols (); + grub_load_modules (); + + /* It is better to set the root device as soon as possible, + for convenience. */ + grub_machine_set_prefix (); + grub_env_export ("prefix"); + grub_set_root_dev (); + + /* Load the normal mode module. */ + grub_load_normal_mode (); + + /* Enter the rescue mode. */ + grub_enter_rescue_mode (); +} diff --git a/kern/misc.c b/kern/misc.c new file mode 100644 index 0000000..641bd7a --- /dev/null +++ b/kern/misc.c @@ -0,0 +1,1089 @@ +/* misc.c - definitions of misc functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +void * +grub_memmove (void *dest, const void *src, grub_size_t n) +{ + char *d = (char *) dest; + const char *s = (const char *) src; + + if (d < s) + while (n--) + *d++ = *s++; + else + { + d += n; + s += n; + + while (n--) + *--d = *--s; + } + + return dest; +} +void *memmove (void *dest, const void *src, grub_size_t n) + __attribute__ ((alias ("grub_memmove"))); +/* GCC emits references to memcpy() for struct copies etc. */ +void *memcpy (void *dest, const void *src, grub_size_t n) + __attribute__ ((alias ("grub_memmove"))); + +char * +grub_strcpy (char *dest, const char *src) +{ + char *p = dest; + + while ((*p++ = *src++) != '\0') + ; + + return dest; +} + +char * +grub_strncpy (char *dest, const char *src, int c) +{ + char *p = dest; + + while ((*p++ = *src++) != '\0' && --c) + ; + + return dest; +} + +char * +grub_stpcpy (char *dest, const char *src) +{ + char *d = dest; + const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} + +char * +grub_strcat (char *dest, const char *src) +{ + char *p = dest; + + while (*p) + p++; + + while ((*p = *src) != '\0') + { + p++; + src++; + } + + return dest; +} + +char * +grub_strncat (char *dest, const char *src, int c) +{ + char *p = dest; + + while (*p) + p++; + + while ((*p = *src) != '\0' && c--) + { + p++; + src++; + } + + *p = '\0'; + + return dest; +} + +int +grub_printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_vprintf (fmt, ap); + va_end (ap); + + return ret; +} + +#ifndef GRUB_UTIL +int grub_err_printf (const char *fmt, ...) +__attribute__ ((alias("grub_printf"))); +#endif + +void +grub_real_dprintf (const char *file, const int line, const char *condition, + const char *fmt, ...) +{ + va_list args; + const char *debug = grub_env_get ("debug"); + + if (! debug) + return; + + if (grub_strword (debug, "all") || grub_strword (debug, condition)) + { + grub_printf ("%s:%d: ", file, line); + va_start (args, fmt); + grub_vprintf (fmt, args); + va_end (args); + } +} + +int +grub_vprintf (const char *fmt, va_list args) +{ + int ret; + + ret = grub_vsprintf (0, fmt, args); + grub_refresh (); + return ret; +} + +int +grub_memcmp (const void *s1, const void *s2, grub_size_t n) +{ + const char *t1 = s1; + const char *t2 = s2; + + while (n--) + { + if (*t1 != *t2) + return (int) *t1 - (int) *t2; + + t1++; + t2++; + } + + return 0; +} +int memcmp (const void *s1, const void *s2, grub_size_t n) + __attribute__ ((alias ("grub_memcmp"))); + +int +grub_strcmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (*s1 != *s2) + break; + + s1++; + s2++; + } + + return (int) *s1 - (int) *s2; +} + +int +grub_strncmp (const char *s1, const char *s2, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (*s1 != *s2) + break; + + s1++; + s2++; + } + + return (int) *s1 - (int) *s2; +} + +int +grub_strcasecmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (grub_tolower (*s1) != grub_tolower (*s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); +} + +int +grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (grub_tolower (*s1) != grub_tolower (*s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower (*s1) - (int) grub_tolower (*s2); +} + +char * +grub_strchr (const char *s, int c) +{ + while (*s) + { + if (*s == c) + return (char *) s; + s++; + } + + return 0; +} + +char * +grub_strrchr (const char *s, int c) +{ + char *p = 0; + + while (*s) + { + if (*s == c) + p = (char *) s; + s++; + } + + return p; +} + +/* Copied from gnulib. + Written by Bruno Haible , 2005. */ +char * +grub_strstr (const char *haystack, const char *needle) +{ + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ + if (*needle != '\0') + { + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; + + for (;; haystack++) + { + if (*haystack == '\0') + /* No match. */ + return NULL; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return NULL; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; +} + +int +grub_strword (const char *haystack, const char *needle) +{ + const char *n_pos = needle; + + while (grub_iswordseparator (*haystack)) + haystack++; + + while (*haystack) + { + /* Crawl both the needle and the haystack word we're on. */ + while(*haystack && !grub_iswordseparator (*haystack) + && *haystack == *n_pos) + { + haystack++; + n_pos++; + } + + /* If we reached the end of both words at the same time, the word + is found. If not, eat everything in the haystack that isn't the + next word (or the end of string) and "reset" the needle. */ + if ( (!*haystack || grub_iswordseparator (*haystack)) + && (!*n_pos || grub_iswordseparator (*n_pos))) + return 1; + else + { + n_pos = needle; + while (*haystack && !grub_iswordseparator (*haystack)) + haystack++; + while (grub_iswordseparator (*haystack)) + haystack++; + } + } + + return 0; +} + +int +grub_iswordseparator (int c) +{ + return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&'); +} + +int +grub_isspace (int c) +{ + return (c == '\n' || c == '\r' || c == ' ' || c == '\t'); +} + +int +grub_isprint (int c) +{ + return (c >= ' ' && c <= '~'); +} + +int +grub_isalpha (int c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +int +grub_isdigit (int c) +{ + return (c >= '0' && c <= '9'); +} + +int +grub_isgraph (int c) +{ + return (c >= '!' && c <= '~'); +} + +int +grub_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + + return c; +} + + +unsigned long +grub_strtoul (const char *str, char **end, int base) +{ + unsigned long long num; + + num = grub_strtoull (str, end, base); + if (num > ~0UL) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected"); + return ~0UL; + } + + return (unsigned long) num; +} + +unsigned long long +grub_strtoull (const char *str, char **end, int base) +{ + unsigned long long num = 0; + int found = 0; + + /* Skip white spaces. */ + while (*str && grub_isspace (*str)) + str++; + + /* Guess the base, if not specified. The prefix `0x' means 16, and + the prefix `0' means 8. */ + if (base == 0 && str[0] == '0') + { + if (str[1] == 'x') + { + if (base == 0 || base == 16) + { + base = 16; + str += 2; + } + } + else if (str[1] >= '0' && str[1] <= '7') + base = 8; + } + + if (base == 0) + base = 10; + + while (*str) + { + unsigned long digit; + + digit = grub_tolower (*str) - '0'; + if (digit > 9) + { + digit += '0' - 'a' + 10; + if (digit >= (unsigned long) base) + break; + } + + found = 1; + + /* NUM * BASE + DIGIT > ~0ULL */ + if (num > grub_divmod64 (~0ULL - digit, base, 0)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected"); + return ~0ULL; + } + + num = num * base + digit; + str++; + } + + if (! found) + { + grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number"); + return 0; + } + + if (end) + *end = (char *) str; + + return num; +} + +char * +grub_strdup (const char *s) +{ + grub_size_t len; + char *p; + + len = grub_strlen (s) + 1; + p = (char *) grub_malloc (len); + if (! p) + return 0; + + return grub_memcpy (p, s, len); +} + +char * +grub_strndup (const char *s, grub_size_t n) +{ + grub_size_t len; + char *p; + + len = grub_strlen (s); + if (len > n) + len = n; + p = (char *) grub_malloc (len + 1); + if (! p) + return 0; + + grub_memcpy (p, s, len); + p[len] = '\0'; + return p; +} + +void * +grub_memset (void *s, int c, grub_size_t n) +{ + unsigned char *p = (unsigned char *) s; + + while (n--) + *p++ = (unsigned char) c; + + return s; +} +void *memset (void *s, int c, grub_size_t n) + __attribute__ ((alias ("grub_memset"))); + +grub_size_t +grub_strlen (const char *s) +{ + const char *p = s; + + while (*p) + p++; + + return p - s; +} + +static inline void +grub_reverse (char *str) +{ + char *p = str + grub_strlen (str) - 1; + + while (str < p) + { + char tmp; + + tmp = *str; + *str = *p; + *p = tmp; + str++; + p--; + } +} + +static char * +grub_itoa (char *str, int c, unsigned n) +{ + unsigned base = (c == 'x') ? 16 : 10; + char *p; + + if ((int) n < 0 && c == 'd') + { + n = (unsigned) (-((int) n)); + *str++ = '-'; + } + + p = str; + do + { + unsigned d = n % base; + *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; + } + while (n /= base); + *p = 0; + + grub_reverse (str); + return p; +} + +/* Divide N by D, return the quotient, and store the remainder in *R. */ +grub_uint64_t +grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r) +{ + /* This algorithm is typically implemented by hardware. The idea + is to get the highest bit in N, 64 times, by keeping + upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper + represents the high 64 bits in 128-bits space. */ + unsigned bits = 64; + unsigned long long q = 0; + unsigned m = 0; + + /* Skip the slow computation if 32-bit arithmetic is possible. */ + if (n < 0xffffffff) + { + if (r) + *r = ((grub_uint32_t) n) % d; + + return ((grub_uint32_t) n) / d; + } + + while (bits--) + { + m <<= 1; + + if (n & (1ULL << 63)) + m |= 1; + + q <<= 1; + n <<= 1; + + if (m >= d) + { + q |= 1; + m -= d; + } + } + + if (r) + *r = m; + + return q; +} + +/* Convert a long long value to a string. This function avoids 64-bit + modular arithmetic or divisions. */ +static char * +grub_lltoa (char *str, int c, unsigned long long n) +{ + unsigned base = (c == 'x') ? 16 : 10; + char *p; + + if ((long long) n < 0 && c == 'd') + { + n = (unsigned long long) (-((long long) n)); + *str++ = '-'; + } + + p = str; + + if (base == 16) + do + { + unsigned d = (unsigned) (n & 0xf); + *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; + } + while (n >>= 4); + else + /* BASE == 10 */ + do + { + unsigned m; + + n = grub_divmod64 (n, 10, &m); + *p++ = m + '0'; + } + while (n); + + *p = 0; + + grub_reverse (str); + return p; +} + +int +grub_vsprintf (char *str, const char *fmt, va_list args) +{ + char c; + int count = 0; + auto void write_char (unsigned char ch); + auto void write_str (const char *s); + auto void write_fill (const char ch, int n); + + void write_char (unsigned char ch) + { + if (str) + *str++ = ch; + else + grub_putchar (ch); + + count++; + } + + void write_str (const char *s) + { + while (*s) + write_char (*s++); + } + + void write_fill (const char ch, int n) + { + int i; + for (i = 0; i < n; i++) + write_char (ch); + } + + while ((c = *fmt++) != 0) + { + if (c != '%') + write_char (c); + else + { + char tmp[32]; + char *p; + unsigned int format1 = 0; + unsigned int format2 = ~ 0U; + char zerofill = ' '; + int rightfill = 0; + int n; + int longfmt = 0; + int longlongfmt = 0; + + if (*fmt && *fmt =='-') + { + rightfill = 1; + fmt++; + } + + p = (char *) fmt; + /* Read formatting parameters. */ + while (*p && grub_isdigit (*p)) + p++; + + if (p > fmt) + { + char s[p - fmt + 1]; + grub_strncpy (s, fmt, p - fmt); + s[p - fmt] = 0; + if (s[0] == '0') + zerofill = '0'; + format1 = grub_strtoul (s, 0, 10); + fmt = p; + } + + if (*p && *p == '.') + { + p++; + fmt++; + while (*p && grub_isdigit (*p)) + p++; + + if (p > fmt) + { + char fstr[p - fmt + 1]; + grub_strncpy (fstr, fmt, p - fmt); + fstr[p - fmt] = 0; + format2 = grub_strtoul (fstr, 0, 10); + fmt = p; + } + } + + c = *fmt++; + if (c == 'l') + { + longfmt = 1; + c = *fmt++; + if (c == 'l') + { + longlongfmt = 1; + c = *fmt++; + } + } + + switch (c) + { + case 'p': + write_str ("0x"); + c = 'x'; + longlongfmt |= (sizeof (void *) == sizeof (long long)); + /* fall through */ + case 'x': + case 'u': + case 'd': + if (longlongfmt) + { + long long ll; + + ll = va_arg (args, long long); + grub_lltoa (tmp, c, ll); + } + else + { + if (longfmt) + n = va_arg (args, long); + else + n = va_arg (args, int); + grub_itoa (tmp, c, n); + } + if (! rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + write_str (tmp); + if (rightfill && grub_strlen (tmp) < format1) + write_fill (zerofill, format1 - grub_strlen (tmp)); + break; + + case 'c': + n = va_arg (args, int); + write_char (n & 0xff); + break; + + case 'C': + { + grub_uint32_t code = va_arg (args, grub_uint32_t); + int shift; + unsigned mask; + + if (code <= 0x7f) + { + shift = 0; + mask = 0; + } + else if (code <= 0x7ff) + { + shift = 6; + mask = 0xc0; + } + else if (code <= 0xffff) + { + shift = 12; + mask = 0xe0; + } + else if (code <= 0x1fffff) + { + shift = 18; + mask = 0xf0; + } + else if (code <= 0x3ffffff) + { + shift = 24; + mask = 0xf8; + } + else if (code <= 0x7fffffff) + { + shift = 30; + mask = 0xfc; + } + else + { + code = '?'; + shift = 0; + mask = 0; + } + + write_char (mask | (code >> shift)); + + for (shift -= 6; shift >= 0; shift -= 6) + write_char (0x80 | (0x3f & (code >> shift))); + } + break; + + case 's': + p = va_arg (args, char *); + if (p) + { + grub_size_t len = 0; + while (len < format2 && p[len]) + len++; + + if (!rightfill && len < format1) + write_fill (zerofill, format1 - len); + + grub_size_t i; + for (i = 0; i < len; i++) + write_char (*p++); + + if (rightfill && len < format1) + write_fill (zerofill, format1 - len); + } + else + write_str ("(null)"); + + break; + + default: + write_char (c); + break; + } + } + } + + if (str) + *str = '\0'; + + if (count && !str) + grub_refresh (); + + return count; +} + +int +grub_sprintf (char *str, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = grub_vsprintf (str, fmt, ap); + va_end (ap); + + return ret; +} + +/* Convert UTF-16 to UTF-8. */ +grub_uint8_t * +grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src, + grub_size_t size) +{ + grub_uint32_t code_high = 0; + + while (size--) + { + grub_uint32_t code = *src++; + + if (code_high) + { + if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + /* Error... */ + *dest++ = '?'; + } + + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + { + /* Error... */ + *dest++ = '?'; + } + else + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + +/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE + bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string. + Return the number of characters converted. DEST must be able to hold + at least DESTSIZE characters. If an invalid sequence is found, return -1. + If SRCEND is not NULL, then *SRCEND is set to the next byte after the + last byte used in SRC. */ +grub_ssize_t +grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, + const grub_uint8_t *src, grub_size_t srcsize, + const grub_uint8_t **srcend) +{ + grub_uint32_t *p = dest; + int count = 0; + grub_uint32_t code = 0; + + if (srcend) + *srcend = src; + + while (srcsize && destsize) + { + grub_uint32_t c = *src++; + if (srcsize != (grub_size_t)-1) + srcsize--; + if (count) + { + if ((c & 0xc0) != 0x80) + { + /* invalid */ + return -1; + } + else + { + code <<= 6; + code |= (c & 0x3f); + count--; + } + } + else + { + if (c == 0) + break; + + if ((c & 0x80) == 0x00) + code = c; + else if ((c & 0xe0) == 0xc0) + { + count = 1; + code = c & 0x1f; + } + else if ((c & 0xf0) == 0xe0) + { + count = 2; + code = c & 0x0f; + } + else if ((c & 0xf8) == 0xf0) + { + count = 3; + code = c & 0x07; + } + else if ((c & 0xfc) == 0xf8) + { + count = 4; + code = c & 0x03; + } + else if ((c & 0xfe) == 0xfc) + { + count = 5; + code = c & 0x01; + } + else + return -1; + } + + if (count == 0) + { + *p++ = code; + destsize--; + } + } + + if (srcend) + *srcend = src; + return p - dest; +} + +/* Abort GRUB. This function does not return. */ +void +grub_abort (void) +{ + if (grub_term_get_current_output ()) + { + grub_printf ("\nAborted."); + + if (grub_term_get_current_input ()) + { + grub_printf (" Press any key to exit."); + grub_getkey (); + } + } + + grub_exit (); +} +/* GCC emits references to abort(). */ +void abort (void) __attribute__ ((alias ("grub_abort"))); + +#ifdef NEED_ENABLE_EXECUTE_STACK +/* Some gcc versions generate a call to this function + in trampolines for nested functions. */ +__enable_execute_stack (void *addr __attribute__ ((unused))) +{ +} +#endif + diff --git a/kern/mm.c b/kern/mm.c new file mode 100644 index 0000000..a31dc2e --- /dev/null +++ b/kern/mm.c @@ -0,0 +1,559 @@ +/* mm.c - functions for memory manager */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + The design of this memory manager. + + This is a simple implementation of malloc with a few extensions. These are + the extensions: + + - memalign is implemented efficiently. + + - multiple regions may be used as free space. They may not be + contiguous. + + Regions are managed by a singly linked list, and the meta information is + stored in the beginning of each region. Space after the meta information + is used to allocate memory. + + The memory space is used as cells instead of bytes for simplicity. This + is important for some CPUs which may not access multiple bytes at a time + when the first byte is not aligned at a certain boundary (typically, + 4-byte or 8-byte). The size of each cell is equal to the size of struct + grub_mm_header, so the header of each allocated/free block fits into one + cell precisely. One cell is 16 bytes on 32-bit platforms and 32 bytes + on 64-bit platforms. + + There are two types of blocks: allocated blocks and free blocks. + + In allocated blocks, the header of each block has only its size. Note that + this size is based on cells but not on bytes. The header is located right + before the returned pointer, that is, the header resides at the previous + cell. + + Free blocks constitutes a ring, using a singly linked list. The first free + block is pointed to by the meta information of a region. The allocator + attempts to pick up the second block instead of the first one. This is + a typical optimization against defragmentation, and makes the + implementation a bit easier. + + For safety, both allocated blocks and free ones are marked by magic + numbers. Whenever anything unexpected is detected, GRUB aborts the + operation. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef MM_DEBUG +# undef grub_malloc +# undef grub_realloc +# undef grub_free +# undef grub_memalign +#endif + +/* Magic words. */ +#define GRUB_MM_FREE_MAGIC 0x2d3c2808 +#define GRUB_MM_ALLOC_MAGIC 0x6db08fa4 + +typedef struct grub_mm_header +{ + struct grub_mm_header *next; + grub_size_t size; + grub_size_t magic; +#if GRUB_CPU_SIZEOF_VOID_P == 4 + char padding[4]; +#elif GRUB_CPU_SIZEOF_VOID_P == 8 + char padding[8]; +#else +# error "unknown word size" +#endif +} +*grub_mm_header_t; + +#if GRUB_CPU_SIZEOF_VOID_P == 4 +# define GRUB_MM_ALIGN_LOG2 4 +#elif GRUB_CPU_SIZEOF_VOID_P == 8 +# define GRUB_MM_ALIGN_LOG2 5 +#endif + +#define GRUB_MM_ALIGN (1 << GRUB_MM_ALIGN_LOG2) + +typedef struct grub_mm_region +{ + struct grub_mm_header *first; + struct grub_mm_region *next; + grub_addr_t addr; + grub_size_t size; +} +*grub_mm_region_t; + + + +static grub_mm_region_t base; + +/* Get a header from the pointer PTR, and set *P and *R to a pointer + to the header and a pointer to its region, respectively. PTR must + be allocated. */ +static void +get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r) +{ + if ((grub_addr_t) ptr & (GRUB_MM_ALIGN - 1)) + grub_fatal ("unaligned pointer %p", ptr); + + for (*r = base; *r; *r = (*r)->next) + if ((grub_addr_t) ptr > (*r)->addr + && (grub_addr_t) ptr <= (*r)->addr + (*r)->size) + break; + + if (! *r) + grub_fatal ("out of range pointer %p", ptr); + + *p = (grub_mm_header_t) ptr - 1; + if ((*p)->magic != GRUB_MM_ALLOC_MAGIC) + grub_fatal ("alloc magic is broken at %p", *p); +} + +/* Initialize a region starting from ADDR and whose size is SIZE, + to use it as free space. */ +void +grub_mm_init_region (void *addr, grub_size_t size) +{ + grub_mm_header_t h; + grub_mm_region_t r, *p, q; + +#if 0 + grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size); +#endif + + /* If this region is too small, ignore it. */ + if (size < GRUB_MM_ALIGN * 2) + return; + + /* Allocate a region from the head. */ + r = (grub_mm_region_t) (((grub_addr_t) addr + GRUB_MM_ALIGN - 1) + & (~(GRUB_MM_ALIGN - 1))); + size -= (char *) r - (char *) addr + sizeof (*r); + + h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN); + h->next = h; + h->magic = GRUB_MM_FREE_MAGIC; + h->size = (size >> GRUB_MM_ALIGN_LOG2); + + r->first = h; + r->addr = (grub_addr_t) h; + r->size = (h->size << GRUB_MM_ALIGN_LOG2); + + /* Find where to insert this region. Put a smaller one before bigger ones, + to prevent fragmentation. */ + for (p = &base, q = *p; q; p = &(q->next), q = *p) + if (q->size > r->size) + break; + + *p = r; + r->next = q; +} + +/* Allocate the number of units N with the alignment ALIGN from the ring + buffer starting from *FIRST. ALIGN must be a power of two. Both N and + ALIGN are in units of GRUB_MM_ALIGN. Return a non-NULL if successful, + otherwise return NULL. */ +static void * +grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) +{ + grub_mm_header_t p, q; + + /* When everything is allocated side effect is that *first will have alloc + magic marked, meaning that there is no room in this region. */ + if ((*first)->magic == GRUB_MM_ALLOC_MAGIC) + return 0; + + /* Try to search free slot for allocation in this memory region. */ + for (q = *first, p = q->next; ; q = p, p = p->next) + { + grub_off_t extra; + + extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) % align; + if (extra) + extra = align - extra; + + if (! p) + grub_fatal ("null in the ring"); + + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic); + + if (p->size >= n + extra) + { + if (extra == 0 && p->size == n) + { + /* There is no special alignment requirement and memory block + is complete match. + + 1. Just mark memory block as allocated and remove it from + free list. + + Result: + +---------------+ previous block's next + | alloc, size=n | | + +---------------+ v + */ + q->next = p->next; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + else if (extra == 0 || p->size == n + extra) + { + /* There might be alignment requirement, when taking it into + account memory block fits in. + + 1. Allocate new area at end of memory block. + 2. Reduce size of available blocks from original node. + 3. Mark new area as allocated and "remove" it from free + list. + + Result: + +---------------+ + | free, size-=n | next --+ + +---------------+ | + | alloc, size=n | | + +---------------+ v + */ + p->size -= n; + p += p->size; + p->size = n; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + else + { + /* There is alignment requirement and there is room in memory + block. Split memory block to three pieces. + + 1. Create new memory block right after section being + allocated. Mark it as free. + 2. Add new memory block to free chain. + 3. Mark current memory block having only extra blocks. + 4. Advance to aligned block and mark that as allocated and + "remove" it from free list. + + Result: + +------------------------------+ + | free, size=extra | next --+ + +------------------------------+ | + | alloc, size=n | | + +------------------------------+ | + | free, size=orig.size-extra-n | <------+, next --+ + +------------------------------+ v + */ + grub_mm_header_t r; + + r = p + extra + n; + r->magic = GRUB_MM_FREE_MAGIC; + r->size = p->size - extra - n; + r->next = p->next; + + p->size = extra; + p->next = r; + p += extra; + p->size = n; + p->magic = GRUB_MM_ALLOC_MAGIC; + } + + /* Mark find as a start marker for next allocation to fasten it. + This will have side effect of fragmenting memory as small + pieces before this will be un-used. */ + *first = q; + + return p + 1; + } + + /* Search was completed without result. */ + if (p == *first) + break; + } + + return 0; +} + +/* Allocate SIZE bytes with the alignment ALIGN and return the pointer. */ +void * +grub_memalign (grub_size_t align, grub_size_t size) +{ + grub_mm_region_t r; + grub_size_t n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1; + int count = 0; + + align = (align >> GRUB_MM_ALIGN_LOG2); + if (align == 0) + align = 1; + + again: + + for (r = base; r; r = r->next) + { + void *p; + + p = grub_real_malloc (&(r->first), n, align); + if (p) + return p; + } + + /* If failed, increase free memory somehow. */ + switch (count) + { + case 0: + /* Invalidate disk caches. */ + grub_disk_cache_invalidate_all (); + count++; + goto again; + + case 1: + /* Unload unneeded modules. */ + grub_dl_unload_unneeded (); + count++; + goto again; + + default: + break; + } + + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + return 0; +} + +/* Allocate SIZE bytes and return the pointer. */ +void * +grub_malloc (grub_size_t size) +{ + return grub_memalign (0, size); +} + +/* Deallocate the pointer PTR. */ +void +grub_free (void *ptr) +{ + grub_mm_header_t p; + grub_mm_region_t r; + + if (! ptr) + return; + + get_header_from_pointer (ptr, &p, &r); + + if (r->first->magic == GRUB_MM_ALLOC_MAGIC) + { + p->magic = GRUB_MM_FREE_MAGIC; + r->first = p->next = p; + } + else + { + grub_mm_header_t q; + +#if 0 + q = r->first; + do + { + grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n", + __FILE__, __LINE__, q, q->size, q->magic); + q = q->next; + } + while (q != r->first); +#endif + + for (q = r->first; q >= p || q->next <= p; q = q->next) + { + if (q->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", q, q->magic); + + if (q >= q->next && (q < p || q->next > p)) + break; + } + + p->magic = GRUB_MM_FREE_MAGIC; + p->next = q->next; + q->next = p; + + if (p + p->size == p->next) + { + if (p->next == q) + q = p; + + p->next->magic = 0; + p->size += p->next->size; + p->next = p->next->next; + } + + if (q + q->size == p) + { + p->magic = 0; + q->size += p->size; + q->next = p->next; + } + + r->first = q; + } +} + +/* Reallocate SIZE bytes and return the pointer. The contents will be + the same as that of PTR. */ +void * +grub_realloc (void *ptr, grub_size_t size) +{ + grub_mm_header_t p; + grub_mm_region_t r; + void *q; + grub_size_t n; + + if (! ptr) + return grub_malloc (size); + + if (! size) + { + grub_free (ptr); + return 0; + } + + /* FIXME: Not optimal. */ + n = ((size + GRUB_MM_ALIGN - 1) >> GRUB_MM_ALIGN_LOG2) + 1; + get_header_from_pointer (ptr, &p, &r); + + if (p->size >= n) + return ptr; + + q = grub_malloc (size); + if (! q) + return q; + + grub_memcpy (q, ptr, size); + grub_free (ptr); + return q; +} + +#ifdef MM_DEBUG +int grub_mm_debug = 0; + +void +grub_mm_dump_free (void) +{ + grub_mm_region_t r; + + for (r = base; r; r = r->next) + { + grub_mm_header_t p; + + /* Follow the free list. */ + p = r->first; + do + { + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", p, p->magic); + + grub_printf ("F:%p:%u:%p\n", + p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next); + p = p->next; + } + while (p != r->first); + } + + grub_printf ("\n"); +} + +void +grub_mm_dump (unsigned lineno) +{ + grub_mm_region_t r; + + grub_printf ("called at line %u\n", lineno); + for (r = base; r; r = r->next) + { + grub_mm_header_t p; + + for (p = (grub_mm_header_t) ((r->addr + GRUB_MM_ALIGN - 1) + & (~(GRUB_MM_ALIGN - 1))); + (grub_addr_t) p < r->addr + r->size; + p++) + { + switch (p->magic) + { + case GRUB_MM_FREE_MAGIC: + grub_printf ("F:%p:%u:%p\n", + p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2, p->next); + break; + case GRUB_MM_ALLOC_MAGIC: + grub_printf ("A:%p:%u\n", p, (unsigned int) p->size << GRUB_MM_ALIGN_LOG2); + break; + } + } + } + + grub_printf ("\n"); +} + +void * +grub_debug_malloc (const char *file, int line, grub_size_t size) +{ + void *ptr; + + if (grub_mm_debug) + grub_printf ("%s:%d: malloc (0x%x) = ", file, line, size); + ptr = grub_malloc (size); + if (grub_mm_debug) + grub_printf ("%p\n", ptr); + return ptr; +} + +void +grub_debug_free (const char *file, int line, void *ptr) +{ + if (grub_mm_debug) + grub_printf ("%s:%d: free (%p)\n", file, line, ptr); + grub_free (ptr); +} + +void * +grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size) +{ + if (grub_mm_debug) + grub_printf ("%s:%d: realloc (%p, 0x%x) = ", file, line, ptr, size); + ptr = grub_realloc (ptr, size); + if (grub_mm_debug) + grub_printf ("%p\n", ptr); + return ptr; +} + +void * +grub_debug_memalign (const char *file, int line, grub_size_t align, + grub_size_t size) +{ + void *ptr; + + if (grub_mm_debug) + grub_printf ("%s:%d: memalign (0x%x, 0x%x) = ", + file, line, align, size); + ptr = grub_memalign (align, size); + if (grub_mm_debug) + grub_printf ("%p\n", ptr); + return ptr; +} + +#endif /* MM_DEBUG */ diff --git a/kern/parser.c b/kern/parser.c new file mode 100644 index 0000000..e931853 --- /dev/null +++ b/kern/parser.c @@ -0,0 +1,229 @@ +/* parser.c - the part of the parser that can return partial tokens */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + + +/* All the possible state transitions on the command line. If a + transition can not be found, it is assumed that there is no + transition and keep_value is assumed to be 1. */ +static struct grub_parser_state_transition state_transitions[] = +{ + { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0}, + { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0}, + { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0}, + { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0}, + + { GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1}, + + { GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0}, + + { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0}, + { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0}, + + { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0}, + { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1}, + { GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1}, + { GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0}, + + { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0}, + { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1}, + { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1}, + { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0}, + { GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0}, + + { 0, 0, 0, 0} +}; + + +/* Determines the state following STATE, determined by C. */ +grub_parser_state_t +grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result) +{ + struct grub_parser_state_transition *transition; + struct grub_parser_state_transition *next_match = 0; + struct grub_parser_state_transition default_transition; + int found = 0; + + default_transition.to_state = state; + default_transition.keep_value = 1; + + /* Look for a good translation. */ + for (transition = state_transitions; transition->from_state; transition++) + { + /* An exact match was found, use it. */ + if (transition->from_state == state && transition->input == c) + { + found = 1; + break; + } + + /* A less perfect match was found, use this one if no exact + match can be found. */ + if (transition->from_state == state && transition->input == 0) + next_match = transition; + } + + if (! found) + { + if (next_match) + transition = next_match; + else + transition = &default_transition; + } + + if (transition->keep_value) + *result = c; + else + *result = 0; + return transition->to_state; +} + + +grub_err_t +grub_parser_split_cmdline (const char *cmdline, grub_err_t (*getline) (char **), + int *argc, char ***argv) +{ + grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; + /* XXX: Fixed size buffer, perhaps this buffer should be dynamically + allocated. */ + char buffer[1024]; + char *bp = buffer; + char *rd = (char *) cmdline; + char varname[200]; + char *vp = varname; + char *args; + int i; + + auto int check_varstate (grub_parser_state_t s); + + int check_varstate (grub_parser_state_t s) + { + return (s == GRUB_PARSER_STATE_VARNAME + || s == GRUB_PARSER_STATE_VARNAME2 + || s == GRUB_PARSER_STATE_QVARNAME + || s == GRUB_PARSER_STATE_QVARNAME2); + } + + auto void add_var (grub_parser_state_t newstate); + + void add_var (grub_parser_state_t newstate) + { + char *val; + + /* Check if a variable was being read in and the end of the name + was reached. */ + if (! (check_varstate (state) && !check_varstate (newstate))) + return; + + *(vp++) = '\0'; + val = grub_env_get (varname); + vp = varname; + if (! val) + return; + + /* Insert the contents of the variable in the buffer. */ + for (; *val; val++) + *(bp++) = *val; + } + + *argc = 1; + do + { + if (! *rd) + { + if (getline) + getline (&rd); + else break; + } + + for (; *rd; rd++) + { + grub_parser_state_t newstate; + char use; + + newstate = grub_parser_cmdline_state (state, *rd, &use); + + /* If a variable was being processed and this character does + not describe the variable anymore, write the variable to + the buffer. */ + add_var (newstate); + + if (check_varstate (newstate)) + { + if (use) + *(vp++) = use; + } + else + { + if (newstate == GRUB_PARSER_STATE_TEXT + && state != GRUB_PARSER_STATE_ESC && use == ' ') + { + /* Don't add more than one argument if multiple + spaces are used. */ + if (bp != buffer && *(bp - 1)) + { + *(bp++) = '\0'; + (*argc)++; + } + } + else if (use) + *(bp++) = use; + } + state = newstate; + } + } while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); + *(bp++) = '\0'; + + /* A special case for when the last character was part of a + variable. */ + add_var (GRUB_PARSER_STATE_TEXT); + + + /* Reserve memory for the return values. */ + args = grub_malloc (bp - buffer); + if (! args) + return grub_errno; + grub_memcpy (args, buffer, bp - buffer); + + *argv = grub_malloc (sizeof (char *) * (*argc + 1)); + if (! *argv) + { + grub_free (args); + return grub_errno; + } + + /* The arguments are separated with 0's, setup argv so it points to + the right values. */ + bp = args; + for (i = 0; i < *argc; i++) + { + (*argv)[i] = bp; + while (*bp) + bp++; + bp++; + } + + (*argc)--; + + return 0; +} diff --git a/kern/partition.c b/kern/partition.c new file mode 100644 index 0000000..cb0e4f7 --- /dev/null +++ b/kern/partition.c @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static grub_partition_map_t grub_partition_map_list; + +void +grub_partition_map_register (grub_partition_map_t partmap) +{ + partmap->next = grub_partition_map_list; + grub_partition_map_list = partmap; +} + +void +grub_partition_map_unregister (grub_partition_map_t partmap) +{ + grub_partition_map_t *p, q; + + for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next) + if (q == partmap) + { + *p = q->next; + break; + } +} + +int +grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap)) +{ + grub_partition_map_t p; + + for (p = grub_partition_map_list; p; p = p->next) + if (hook (p)) + return 1; + + return 0; +} + +grub_partition_t +grub_partition_probe (struct grub_disk *disk, const char *str) +{ + grub_partition_t part = 0; + + auto int part_map_probe (const grub_partition_map_t partmap); + + int part_map_probe (const grub_partition_map_t partmap) + { + part = partmap->probe (disk, str); + if (part) + return 1; + + if (grub_errno == GRUB_ERR_BAD_PART_TABLE) + { + /* Continue to next partition map type. */ + grub_errno = GRUB_ERR_NONE; + return 0; + } + + return 1; + } + + /* Use the first partition map type found. */ + grub_partition_map_iterate (part_map_probe); + + return part; +} + +int +grub_partition_iterate (struct grub_disk *disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + grub_partition_map_t partmap = 0; + int ret = 0; + + auto int part_map_iterate (const grub_partition_map_t p); + auto int part_map_iterate_hook (grub_disk_t d, + const grub_partition_t partition); + + int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition __attribute__ ((unused))) + { + return 1; + } + + int part_map_iterate (const grub_partition_map_t p) + { + grub_dprintf ("partition", "Detecting %s...\n", p->name); + p->iterate (disk, part_map_iterate_hook); + + if (grub_errno != GRUB_ERR_NONE) + { + /* Continue to next partition map type. */ + grub_dprintf ("partition", "%s detection failed.\n", p->name); + grub_errno = GRUB_ERR_NONE; + return 0; + } + + grub_dprintf ("partition", "%s detection succeeded.\n", p->name); + partmap = p; + return 1; + } + + grub_partition_map_iterate (part_map_iterate); + if (partmap) + ret = partmap->iterate (disk, hook); + + return ret; +} + +char * +grub_partition_get_name (const grub_partition_t partition) +{ + return partition->partmap->get_name (partition); +} diff --git a/kern/powerpc/cache.S b/kern/powerpc/cache.S new file mode 100644 index 0000000..da982af --- /dev/null +++ b/kern/powerpc/cache.S @@ -0,0 +1,48 @@ +/* cache.S - Flush the processor cache for a specific region. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define CACHE_LINE_BYTES 32 + + .text + + .align 2 + .globl grub_arch_sync_caches +grub_arch_sync_caches: + /* `address' may not be CACHE_LINE_BYTES-aligned. */ + andi. 6, 3, CACHE_LINE_BYTES - 1 /* Find the misalignment. */ + add 4, 4, 6 /* Adjust `size' to compensate. */ + + /* Force the dcache lines to memory. */ + li 5, 0 +1: dcbst 5, 3 + addi 5, 5, CACHE_LINE_BYTES + cmpw 5, 4 + blt 1b + sync /* Force all dcbsts to complete. */ + + /* Invalidate the icache lines. */ + li 5, 0 +1: icbi 5, 3 + addi 5, 5, CACHE_LINE_BYTES + cmpw 5, 4 + blt 1b + sync /* Force all icbis to complete. */ + isync /* Discard partially executed instructions that were + loaded from the invalid icache. */ + blr diff --git a/kern/powerpc/dl.c b/kern/powerpc/dl.c new file mode 100644 index 0000000..0663a96 --- /dev/null +++ b/kern/powerpc/dl.c @@ -0,0 +1,138 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS32 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_PPC) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf32_Ehdr *e = ehdr; + Elf32_Shdr *s; + Elf32_Sym *symtab; + Elf32_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf32_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf32_Rela *rel, *max; + + for (rel = (Elf32_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf32_Word *addr; + Elf32_Sym *sym; + grub_uint32_t value; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf32_Sym *) ((char *) symtab + + entsize * ELF32_R_SYM (rel->r_info)); + + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_PPC_ADDR16_LO: + *(Elf32_Half *) addr = value; + break; + + case R_PPC_REL24: + { + Elf32_Sword delta = value - (Elf32_Word) addr; + + if (delta << 6 >> 6 != delta) + return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow"); + *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); + break; + } + + case R_PPC_ADDR16_HA: + *(Elf32_Half *) addr = (value + 0x8000) >> 16; + break; + + case R_PPC_ADDR32: + *addr = value; + break; + + case R_PPC_REL32: + *addr = value - (Elf32_Word) addr; + break; + + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "This relocation (%d) is not implemented yet", + ELF32_R_TYPE (rel->r_info)); + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S new file mode 100644 index 0000000..4b18fd7 --- /dev/null +++ b/kern/powerpc/ieee1275/startup.S @@ -0,0 +1,64 @@ +/* startup.S - Startup code for the PowerPC. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +.extern __bss_start +.extern _end + + .text + .align 2 + .globl start, _start +start: +_start: + b codestart + + . = EXT_C(start) + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + /* to be filled by grub-mkelfimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + GRUB_KERNEL_CPU_DATA_END + +codestart: + li 2, 0 + li 13, 0 + + /* Stage1 won't zero BSS for us. In other cases, why not do it again? */ + lis 6, (__bss_start - 4)@h + ori 6, 6, (__bss_start - 4)@l + lis 7, (_end - 4)@h + ori 7, 7, (_end - 4)@l + subf 7, 6, 7 + srwi 7, 7, 2 /* We store 4 bytes at a time. */ + mtctr 7 +2: stwu 2, 4(6) /* We know r2 is already 0 from above. */ + bdnz 2b + + /* Store r5 in grub_ieee1275_entry_fn. */ + lis 9, grub_ieee1275_entry_fn@ha + stw 5, grub_ieee1275_entry_fn@l(9) + + bl grub_main +1: b 1b diff --git a/kern/rescue.c b/kern/rescue.c new file mode 100644 index 0000000..e333ab5 --- /dev/null +++ b/kern/rescue.c @@ -0,0 +1,709 @@ +/* rescue.c - rescue mode */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_RESCUE_BUF_SIZE 256 +#define GRUB_RESCUE_MAX_ARGS 20 + +struct grub_rescue_command +{ + const char *name; + void (*func) (int argc, char *argv[]); + const char *message; + struct grub_rescue_command *next; +}; +typedef struct grub_rescue_command *grub_rescue_command_t; + +static char linebuf[GRUB_RESCUE_BUF_SIZE]; + +static grub_rescue_command_t grub_rescue_command_list; + +void +grub_rescue_register_command (const char *name, + void (*func) (int argc, char *argv[]), + const char *message) +{ + grub_rescue_command_t cmd; + + cmd = (grub_rescue_command_t) grub_malloc (sizeof (*cmd)); + if (! cmd) + return; + + cmd->name = name; + cmd->func = func; + cmd->message = message; + + cmd->next = grub_rescue_command_list; + grub_rescue_command_list = cmd; +} + +void +grub_rescue_unregister_command (const char *name) +{ + grub_rescue_command_t *p, q; + + for (p = &grub_rescue_command_list, q = *p; q; p = &(q->next), q = q->next) + if (grub_strcmp (name, q->name) == 0) + { + *p = q->next; + grub_free (q); + break; + } +} + +/* Prompt to input a command and read the line. */ +static void +grub_rescue_get_command_line (const char *prompt) +{ + int c; + int pos = 0; + + grub_printf (prompt); + grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); + + while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r') + { + if (grub_isprint (c)) + { + if (pos < GRUB_RESCUE_BUF_SIZE - 1) + { + linebuf[pos++] = c; + grub_putchar (c); + } + } + else if (c == '\b') + { + if (pos > 0) + { + linebuf[--pos] = 0; + grub_putchar (c); + grub_putchar (' '); + grub_putchar (c); + } + } + grub_refresh (); + } + + grub_putchar ('\n'); + grub_refresh (); +} + +/* boot */ +static void +grub_rescue_cmd_boot (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_loader_boot (); +} + +/* cat FILE */ +static void +grub_rescue_cmd_cat (int argc, char *argv[]) +{ + grub_file_t file; + char buf[GRUB_DISK_SECTOR_SIZE]; + grub_ssize_t size; + + if (argc < 1) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + + file = grub_file_open (argv[0]); + if (! file) + return; + + while ((size = grub_file_read (file, buf, sizeof (buf))) > 0) + { + int i; + + for (i = 0; i < size; i++) + { + unsigned char c = buf[i]; + + if ((grub_isprint (c) || grub_isspace (c)) && c != '\r') + grub_putchar (c); + else + { + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("<%x>", (int) c); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + } + } + } + + grub_putchar ('\n'); + grub_refresh (); + grub_file_close (file); +} + +static int +grub_rescue_print_devices (const char *name) +{ + grub_printf ("(%s) ", name); + + return 0; +} + +static int +grub_rescue_print_files (const char *filename, int dir) +{ + grub_printf ("%s%s ", filename, dir ? "/" : ""); + + return 0; +} + +/* ls [ARG] */ +static void +grub_rescue_cmd_ls (int argc, char *argv[]) +{ + if (argc < 1) + { + grub_device_iterate (grub_rescue_print_devices); + grub_putchar ('\n'); + grub_refresh (); + } + else + { + char *device_name; + grub_device_t dev; + grub_fs_t fs; + char *path; + + device_name = grub_file_get_device_name (argv[0]); + dev = grub_device_open (device_name); + if (! dev) + goto fail; + + fs = grub_fs_probe (dev); + path = grub_strchr (argv[0], ')'); + if (! path) + path = argv[0]; + else + path++; + + if (! path && ! device_name) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); + goto fail; + } + + if (! path) + { + if (grub_errno == GRUB_ERR_UNKNOWN_FS) + grub_errno = GRUB_ERR_NONE; + + grub_printf ("(%s): Filesystem is %s.\n", + device_name, fs ? fs->name : "unknown"); + } + else if (fs) + { + (fs->dir) (dev, path, grub_rescue_print_files); + grub_putchar ('\n'); + grub_refresh (); + } + + fail: + if (dev) + grub_device_close (dev); + + grub_free (device_name); + } +} + +/* help */ +static void +grub_rescue_cmd_help (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_rescue_command_t p, q; + + /* Sort the commands. This is not a good algorithm, but this is enough, + because rescue mode has a small number of commands. */ + for (p = grub_rescue_command_list; p; p = p->next) + for (q = p->next; q; q = q->next) + if (grub_strcmp (p->name, q->name) > 0) + { + struct grub_rescue_command tmp; + + tmp.name = p->name; + tmp.func = p->func; + tmp.message = p->message; + + p->name = q->name; + p->func = q->func; + p->message = q->message; + + q->name = tmp.name; + q->func = tmp.func; + q->message = tmp.message; + } + + /* Print them. */ + for (p = grub_rescue_command_list; p; p = p->next) + grub_printf ("%s\t%s\n", p->name, p->message); +} + +#if 0 +static void +grub_rescue_cmd_info (void) +{ + extern void grub_disk_cache_get_performance (unsigned long *, + unsigned long *); + unsigned long hits, misses; + + grub_disk_cache_get_performance (&hits, &misses); + grub_printf ("Disk cache: hits = %u, misses = %u ", hits, misses); + if (hits + misses) + { + unsigned long ratio = hits * 10000 / (hits + misses); + grub_printf ("(%u.%u%%)\n", ratio / 100, ratio % 100); + } + else + grub_printf ("(N/A)\n"); +} +#endif + +/* root [DEVICE] */ +static void +grub_rescue_cmd_root (int argc, char *argv[]) +{ + grub_device_t dev; + grub_fs_t fs; + + if (argc > 0) + { + char *device_name = grub_file_get_device_name (argv[0]); + if (! device_name) + return; + + grub_env_set ("root", device_name); + grub_free (device_name); + } + + dev = grub_device_open (0); + if (! dev) + return; + + fs = grub_fs_probe (dev); + if (grub_errno == GRUB_ERR_UNKNOWN_FS) + grub_errno = GRUB_ERR_NONE; + + grub_printf ("(%s): Filesystem is %s.\n", + grub_env_get ("root"), fs ? fs->name : "unknown"); + + grub_device_close (dev); +} + +#if 0 +static void +grub_rescue_cmd_testload (int argc, char *argv[]) +{ + grub_file_t file; + char *buf; + grub_ssize_t size; + grub_ssize_t pos; + auto void read_func (unsigned long sector, unsigned offset, unsigned len); + + void read_func (unsigned long sector __attribute__ ((unused)), + unsigned offset __attribute__ ((unused)), + unsigned len __attribute__ ((unused))) + { + grub_putchar ('.'); + grub_refresh (); + } + + if (argc < 1) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + + file = grub_file_open (argv[0]); + if (! file) + return; + + size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1); + if (size == 0) + { + grub_file_close (file); + return; + } + + buf = grub_malloc (size); + if (! buf) + goto fail; + + grub_printf ("Reading %s sequentially", argv[0]); + file->read_hook = read_func; + if (grub_file_read (file, buf, size) != size) + goto fail; + grub_printf (" Done.\n"); + + /* Read sequentially again. */ + grub_printf ("Reading %s sequentially again", argv[0]); + if (grub_file_seek (file, 0) < 0) + goto fail; + + for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE) + { + char sector[GRUB_DISK_SECTOR_SIZE]; + + if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) + goto fail; + + if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0) + { + grub_printf ("\nDiffers in %d\n", pos); + goto fail; + } + } + grub_printf (" Done.\n"); + + /* Read backwards and compare. */ + grub_printf ("Reading %s backwards", argv[0]); + pos = size; + while (pos > 0) + { + char sector[GRUB_DISK_SECTOR_SIZE]; + + pos -= GRUB_DISK_SECTOR_SIZE; + + if (grub_file_seek (file, pos) < 0) + goto fail; + + if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) + goto fail; + + if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0) + { + int i; + + grub_printf ("\nDiffers in %d\n", pos); + + for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++) + grub_putchar (buf[pos + i]); + + if (i) + grub_refresh (); + + goto fail; + } + } + grub_printf (" Done.\n"); + + fail: + + grub_file_close (file); + grub_free (buf); +} +#endif + +/* dump ADDRESS [SIZE] */ +static void +grub_rescue_cmd_dump (int argc, char *argv[]) +{ + grub_uint8_t *addr; + grub_size_t size = 4; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified"); + return; + } + + addr = (grub_uint8_t *) grub_strtoul (argv[0], 0, 0); + if (grub_errno) + return; + + if (argc > 1) + size = (grub_size_t) grub_strtoul (argv[1], 0, 0); + + while (size--) + { + grub_printf ("%x%x ", *addr >> 4, *addr & 0xf); + addr++; + } +} + +/* insmod MODULE */ +static void +grub_rescue_cmd_insmod (int argc, char *argv[]) +{ + char *p; + grub_dl_t mod; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + return; + } + + p = grub_strchr (argv[0], '/'); + if (! p) + mod = grub_dl_load (argv[0]); + else + mod = grub_dl_load_file (argv[0]); + + if (mod) + grub_dl_ref (mod); +} + +/* rmmod MODULE */ +static void +grub_rescue_cmd_rmmod (int argc, char *argv[]) +{ + grub_dl_t mod; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + return; + } + + mod = grub_dl_get (argv[0]); + if (! mod) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module"); + return; + } + + if (grub_dl_unref (mod) <= 0) + grub_dl_unload (mod); +} + +/* lsmod */ +static void +grub_rescue_cmd_lsmod (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + auto int print_module (grub_dl_t mod); + + int print_module (grub_dl_t mod) + { + grub_dl_dep_t dep; + + grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); + for (dep = mod->dep; dep; dep = dep->next) + { + if (dep != mod->dep) + grub_putchar (','); + + grub_printf ("%s", dep->mod->name); + } + grub_putchar ('\n'); + grub_refresh (); + + return 0; + } + + grub_printf ("Name\tRef Count\tDependencies\n"); + grub_dl_iterate (print_module); +} + +/* set ENVVAR=VALUE */ +static void +grub_rescue_cmd_set (int argc, char *argv[]) +{ + char *var; + char *val; + + auto int print_env (struct grub_env_var *env); + + int print_env (struct grub_env_var *env) + { + grub_printf ("%s=%s\n", env->name, env->value); + return 0; + } + + if (argc < 1) + { + grub_env_iterate (print_env); + return; + } + + var = argv[0]; + val = grub_strchr (var, '='); + if (! val) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment"); + return; + } + + val[0] = 0; + grub_env_set (var, val + 1); + val[0] = '='; +} + +static void +grub_rescue_cmd_unset (int argc, char *argv[]) +{ + if (argc < 1) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no environment variable specified"); + return; + } + + grub_env_unset (argv[0]); +} + +/* exit */ +static void +grub_rescue_cmd_exit (int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_exit (); +} + +static void +attempt_normal_mode (void) +{ + grub_rescue_command_t cmd; + + for (cmd = grub_rescue_command_list; cmd; cmd = cmd->next) + { + if (grub_strcmp ("normal", cmd->name) == 0) + { + (cmd->func) (0, 0); + break; + } + } +} + +/* Enter the rescue mode. */ +void +grub_enter_rescue_mode (void) +{ + auto grub_err_t getline (char **line); + + grub_err_t getline (char **line) + { + grub_rescue_get_command_line ("> "); + *line = linebuf; + return 0; + } + + /* First of all, attempt to execute the normal mode. */ + attempt_normal_mode (); + + grub_printf ("Entering rescue mode...\n"); + + grub_rescue_register_command ("boot", grub_rescue_cmd_boot, + "boot an operating system"); + grub_rescue_register_command ("cat", grub_rescue_cmd_cat, + "show the contents of a file"); + grub_rescue_register_command ("help", grub_rescue_cmd_help, + "show this message"); + grub_rescue_register_command ("ls", grub_rescue_cmd_ls, + "list devices or files"); + grub_rescue_register_command ("root", grub_rescue_cmd_root, + "set the root device"); + grub_rescue_register_command ("dump", grub_rescue_cmd_dump, + "dump memory"); + grub_rescue_register_command ("insmod", grub_rescue_cmd_insmod, + "insert a module"); + grub_rescue_register_command ("rmmod", grub_rescue_cmd_rmmod, + "remove a module"); + grub_rescue_register_command ("lsmod", grub_rescue_cmd_lsmod, + "show loaded modules"); + grub_rescue_register_command ("set", grub_rescue_cmd_set, + "set an environment variable"); + grub_rescue_register_command ("unset", grub_rescue_cmd_unset, + "remove an environment variable"); + grub_rescue_register_command ("exit", grub_rescue_cmd_exit, + "exit from GRUB"); + + while (1) + { + char *line = linebuf; + char *name; + int n; + grub_rescue_command_t cmd; + char **args; + + /* Print an error, if any. */ + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + /* Get a command line. */ + grub_rescue_get_command_line ("grub rescue> "); + if (line[0] == 0) + continue; + + if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) + continue; + + /* In case of an assignment set the environment accordingly + instead of calling a function. */ + if (n == 0 && grub_strchr (line, '=')) + { + char *val = grub_strchr (args[0], '='); + val[0] = 0; + grub_env_set (args[0], val + 1); + val[0] = '='; + grub_free (args[0]); + continue; + } + + /* Get the command name. */ + name = args[0]; + + /* If nothing is specified, restart. */ + if (*name == '\0') + { + grub_free (args[0]); + continue; + } + + /* Find the command and execute it. */ + for (cmd = grub_rescue_command_list; cmd; cmd = cmd->next) + { + if (grub_strcmp (name, cmd->name) == 0) + { + (cmd->func) (n, &args[1]); + break; + } + } + + /* If not found, print an error message. */ + if (! cmd) + { + grub_printf ("Unknown command `%s'\n", name); + grub_printf ("Try `help' for usage\n"); + } + + grub_free (args[0]); + } +} diff --git a/kern/sparc64/cache.S b/kern/sparc64/cache.S new file mode 100644 index 0000000..2ebb693 --- /dev/null +++ b/kern/sparc64/cache.S @@ -0,0 +1,43 @@ +/* cache.S - Flush the processor cache for a specific region. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "cache.S" + + .text + +/* + * void grub_arch_sync_caches (void *address, grub_size_t len) + */ +FUNCTION(grub_arch_sync_caches) + save %o6, -0xC, %o6 ! Get a new register window, + ! reserve space on stack for + ! %i0, %i1, %i2 + brz,pn %i0, return ! Return if address == 0. + nop + brz,pn %i1, return ! Return if len == 0. + clr %i2 ! index = 0. +loop: flush %i0 + %i2 ! Flush address + index. + cmp %i1, %i2 ! Compare len & index . + bpos,a,pt %xcc, loop ! If len > index, loop. + add %i2, 8, %i2 ! Go to next doubleword. +return: ret ! Restore caller's register + restore ! window and return. + diff --git a/kern/sparc64/dl.c b/kern/sparc64/dl.c new file mode 100644 index 0000000..28ea352 --- /dev/null +++ b/kern/sparc64/dl.c @@ -0,0 +1,138 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf64_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_SPARCV9) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf64_Ehdr *e = ehdr; + Elf64_Shdr *s; + Elf64_Sym *symtab; + Elf64_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf64_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf64_Rela *rel, *max; + + for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf64_Word *addr; + Elf64_Sym *sym; + Elf64_Addr value; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf64_Sym *) ((char *) symtab + + entsize * ELF64_R_SYM (rel->r_info)); + + value = sym->st_value + rel->r_addend; + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_SPARC_32: /* 3 V-word32 */ + if (value & 0xFFFFFFFF00000000) + return grub_error (GRUB_ERR_BAD_MODULE, + "Address out of 32 bits range"); + *addr = value; + break; + case R_SPARC_WDISP30: /* 7 V-disp30 */ + if (((value - (Elf64_Addr) addr) & 0xFFFFFFFF00000000) && + ((value - (Elf64_Addr) addr) & 0xFFFFFFFF00000000 + != 0xFFFFFFFF00000000)) + return grub_error (GRUB_ERR_BAD_MODULE, + "Displacement out of 30 bits range"); + *addr = (*addr & 0xC0000000) | + (((grub_int32_t) ((value - (Elf64_Addr) addr) >> 2)) & + 0x3FFFFFFF); + break; + case R_SPARC_HI22: /* 9 V-imm22 */ + if (((grub_int32_t) value) & 0xFF00000000) + return grub_error (GRUB_ERR_BAD_MODULE, + "High address out of 22 bits range"); + *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); + break; + case R_SPARC_LO10: /* 12 T-simm13 */ + *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF); + break; + case R_SPARC_64: /* 32 V-xwords64 */ + *(Elf64_Xword *) addr = value; + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "This relocation (%d) is not implemented yet", + ELF64_R_TYPE (rel->r_info)); + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c new file mode 100644 index 0000000..a342557 --- /dev/null +++ b/kern/sparc64/ieee1275/init.c @@ -0,0 +1,237 @@ +/* init.c -- Initialize GRUB on the Ultra Sprac (sparc64). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* OpenBoot entry point. */ +int (*grub_ieee1275_entry_fn) (void *); +grub_ieee1275_phandle_t grub_ieee1275_chosen; +static grub_uint32_t grub_ieee1275_flags; +/* FIXME (sparc64). */ +static const grub_addr_t grub_heap_start = 0x40000; +static grub_addr_t grub_heap_len; + +void +_start (uint64_t r0 __attribute__((unused)), + uint64_t r1 __attribute__((unused)), + uint64_t r2 __attribute__((unused)), + uint64_t r3 __attribute__((unused)), + uint64_t r4, + uint64_t r5 __attribute__((unused))); +void +_start (uint64_t r0 __attribute__((unused)), + uint64_t r1 __attribute__((unused)), + uint64_t r2 __attribute__((unused)), + uint64_t r3 __attribute__((unused)), + uint64_t r4, + uint64_t r5 __attribute__((unused))) +{ + grub_ieee1275_entry_fn = (int (*)(void *)) r4; + + grub_ieee1275_finddevice ("/chosen", &grub_ieee1275_chosen); + + /* Now invoke the main function. */ + grub_main (); + + /* Never reached. */ +} + +int +grub_ieee1275_test_flag (enum grub_ieee1275_flag flag) +{ + return (grub_ieee1275_flags & (1 << flag)); +} + +void +grub_ieee1275_set_flag (enum grub_ieee1275_flag flag) +{ + grub_ieee1275_flags |= (1 << flag); +} + +/* Translate an OF filesystem path (separated by backslashes), into a GRUB + path (separated by forward slashes). */ +static void +grub_translate_ieee1275_path (char *filepath) +{ + char *backslash; + + backslash = grub_strchr (filepath, '\\'); + while (backslash != 0) + { + *backslash = '/'; + backslash = grub_strchr (filepath, '\\'); + } +} + +void +grub_machine_set_prefix (void) +{ + char bootpath[64]; /* XXX check length */ + char *filename; + char *prefix; + + if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, + sizeof (bootpath), 0)) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + grub_env_set ("prefix", ""); + return; + } + + /* Transform an OF device path to a GRUB path. */ + + prefix = grub_ieee1275_encode_devname (bootpath); + + filename = grub_ieee1275_get_filename (bootpath); + if (filename) + { + char *newprefix; + char *lastslash = grub_strrchr (filename, '\\'); + + /* Truncate at last directory. */ + if (lastslash) + { + *lastslash = '\0'; + grub_translate_ieee1275_path (filename); + + newprefix = grub_malloc (grub_strlen (prefix) + + grub_strlen (filename)); + grub_sprintf (newprefix, "%s%s", prefix, filename); + grub_free (prefix); + prefix = newprefix; + } + } + + grub_env_set ("prefix", prefix); + + grub_free (filename); + grub_free (prefix); +} + +grub_uint64_t ieee1275_get_time_ms (void); + +void +grub_machine_init (void) +{ + char *args; + grub_ssize_t length; + + grub_console_init (); + + /* FIXME (sparc64). */ + grub_heap_len = (grub_addr_t) &_start - 0x1000 - grub_heap_start; + + if (grub_ieee1275_claim (grub_heap_start, grub_heap_len, 0, 0)) + grub_fatal ("Failed to claim heap at %p, len 0x%x\n", grub_heap_start, + grub_heap_len); + grub_mm_init_region ((void *) grub_heap_start, grub_heap_len); + + grub_ofdisk_init (); + + /* Process commandline. */ + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootargs", + &length) == 0 && + length > 0) + { + grub_ssize_t i = 0; + + args = grub_malloc (length); + grub_ieee1275_get_property (grub_ieee1275_chosen, "bootargs", args, + length, 0); + + while (i < length) + { + char *command = &args[i]; + char *end; + char *val; + + end = grub_strchr (command, ';'); + if (end == 0) + i = length; /* No more commands after this one. */ + else + { + *end = '\0'; + i += end - command + 1; + while (grub_isspace(args[i])) + i++; + } + + /* Process command. */ + val = grub_strchr (command, '='); + if (val) + { + *val = '\0'; + grub_env_set (command, val + 1); + } + } + } + + grub_install_get_time_ms (ieee1275_get_time_ms); +} + +void +grub_machine_fini (void) +{ + grub_ofdisk_fini (); + grub_console_fini (); +} + +void +grub_exit (void) +{ + grub_ieee1275_enter (); +} + +grub_uint64_t +ieee1275_get_time_ms (void) +{ + return grub_get_rtc (); +} + +grub_uint32_t +grub_get_rtc (void) +{ + grub_uint32_t msecs; + + if (grub_ieee1275_milliseconds (&msecs)) + return 0; + + return msecs; +} + +grub_addr_t +grub_arch_modules_addr (void) +{ + return GRUB_IEEE1275_MODULE_BASE; +} diff --git a/kern/sparc64/ieee1275/openfw.c b/kern/sparc64/ieee1275/openfw.c new file mode 100644 index 0000000..fe9ee96 --- /dev/null +++ b/kern/sparc64/ieee1275/openfw.c @@ -0,0 +1,373 @@ +/* openfw.c -- Open firmware support functions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include /* Needed ? */ +#include + +enum grub_ieee1275_parse_type +{ + GRUB_PARSE_FILENAME, + GRUB_PARSE_PARTITION, +}; + +/* Walk children of 'devpath', calling hook for each. */ +grub_err_t +grub_children_iterate (char *devpath, + int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + grub_ieee1275_phandle_t dev; + grub_ieee1275_phandle_t child; + + grub_ieee1275_finddevice (devpath, &dev); + if (((signed) dev) == -1) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown device"); + + grub_ieee1275_child (dev, &child); + if (((signed) child) == -1) + return grub_error (GRUB_ERR_BAD_DEVICE, "Device has no children"); + + do + { + /* XXX: Don't use hardcoded path lengths. */ + char childtype[64]; + char childpath[64]; + char childname[64]; + char fullname[64]; + struct grub_ieee1275_devalias alias; + grub_ssize_t actual; + + grub_ieee1275_get_property (child, "device_type", childtype, + sizeof childtype, &actual); + if (actual == -1) + continue; + + grub_ieee1275_package_to_path (child, childpath, sizeof childpath, + &actual); + if (actual == -1) + continue; + + grub_ieee1275_get_property (child, "name", childname, + sizeof childname, &actual); + if (actual == -1) + continue; + + grub_sprintf (fullname, "%s/%s", devpath, childname); + + alias.type = childtype; + alias.path = childpath; + alias.name = fullname; + hook (&alias); + } + while (grub_ieee1275_peer (child, &child)); + + return 0; +} + +/* Iterate through all device aliases. This function can be used to + find a device of a specific type. */ +grub_err_t +grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + grub_ieee1275_phandle_t devalias; + char aliasname[32]; + grub_ssize_t actual; + grub_ieee1275_cell_t flags; + struct grub_ieee1275_devalias alias; + + if (grub_ieee1275_finddevice ("/aliases", &devalias)) + return -1; + + aliasname[0] = '\0'; + + while (grub_ieee1275_next_property (devalias, aliasname, aliasname, &flags) != -1 + && ((signed) flags) != -1 ) + { + grub_ieee1275_phandle_t dev; + grub_ssize_t pathlen, typelen; + char *devpath, *devtype; + + grub_dprintf ("devalias", "devalias name = %s\n", aliasname); + + /* The property `name' is a special case we should skip. */ + if (!grub_strcmp (aliasname, "name")) + continue; + + grub_ieee1275_get_property_length (devalias, aliasname, &pathlen); + devpath = grub_malloc (pathlen); + if (! devpath) + return grub_errno; + + if (grub_ieee1275_get_property (devalias, aliasname, devpath, pathlen, + &actual)) + { + grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname); + grub_free (devpath); + continue; + } + + if (grub_ieee1275_finddevice (devpath, &dev) || ((signed) dev) == -1) + { + grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath); + grub_free (devpath); + continue; + } + + grub_ieee1275_get_property_length (dev, "device_type", &typelen); + devtype = grub_malloc (typelen); + if (! devtype) + { + grub_free (devpath); + return grub_errno; + } + if (grub_ieee1275_get_property (dev, "device_type", devtype, typelen, &actual)) + { + grub_dprintf ("devalias", "get device type failed\n"); + grub_free (devtype); + grub_free (devpath); + continue; + } + + alias.name = aliasname; + alias.path= devpath; + alias.type = devtype; + if((*hook) (&alias)) + { + grub_free (devtype); + grub_free (devpath); + break; + } + + grub_free (devtype); + grub_free (devpath); + } + + return 0; +} + +/* FIXME (sparc64) */ +#if 0 +/* Call the "map" method of /chosen/mmu. */ +static int +grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size, + grub_uint8_t mode) +{ + struct map_args { + struct grub_ieee1275_common_hdr common; + char *method; + grub_ieee1275_ihandle_t ihandle; + grub_uint32_t mode; + grub_uint32_t size; + grub_uint32_t virt; + grub_uint32_t phys; + int catch_result; + } args; + grub_ieee1275_ihandle_t mmu; + grub_ssize_t len; + + grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "mmu", &mmu, sizeof mmu, + &len); + if (len != sizeof mmu) + return -1; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1); + args.method = "map"; + args.ihandle = mmu; + args.phys = phys; + args.virt = virt; + args.size = size; + args.mode = mode; /* Format is WIMG0PP. */ + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + return args.catch_result; +} +#endif + +int +grub_claimmap (grub_addr_t addr, grub_size_t size) +{ + if (grub_ieee1275_claim (addr, size, 0, 0)) + return -1; + return 0; +} + +/* Get the device arguments of the Open Firmware node name `path'. */ +static char * +grub_ieee1275_get_devargs (const char *path) +{ + char *colon = grub_strchr (path, ':'); + + if (! colon) + return 0; + + return grub_strdup (colon + 1); +} + +/* Get the device path of the Open Firmware node name `path'. */ +static char * +grub_ieee1275_get_devname (const char *path) +{ + char *colon = grub_strchr (path, ':'); + char *newpath = 0; + int pathlen = grub_strlen (path); + auto int match_alias (struct grub_ieee1275_devalias *alias); + + int match_alias (struct grub_ieee1275_devalias *curalias) + { + /* briQ firmware can change capitalization in /chosen/bootpath. */ + if (! grub_strncasecmp (curalias->path, path, pathlen)) + { + newpath = grub_strndup (curalias->name, grub_strlen (curalias->name)); + return 1; + } + + return 0; + } + + if (colon) + pathlen = (int)(colon - path); + + /* Try to find an alias for this device. */ + grub_devalias_iterate (match_alias); + + if (! newpath) + newpath = grub_strdup (path); + + return newpath; +} + +static char * +grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) +{ + char type[64]; /* XXX check size. */ + char *device = grub_ieee1275_get_devname (path); + char *args = grub_ieee1275_get_devargs (path); + char *ret = 0; + grub_ieee1275_phandle_t dev; + + if (!args) + /* Shouldn't happen. */ + return 0; + + /* We need to know what type of device it is in order to parse the full + file path properly. */ + if (grub_ieee1275_finddevice (device, &dev)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device); + goto fail; + } + if (grub_ieee1275_get_property (dev, "device_type", type, sizeof type, 0)) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Device %s lacks a device_type property\n", device); + goto fail; + } + + if (!grub_strcmp ("block", type)) + { + /* The syntax of the device arguments is defined in the CHRP and PReP + IEEE1275 bindings: "[partition][,[filename]]". */ + char *comma = grub_strchr (args, ','); + + if (ptype == GRUB_PARSE_FILENAME) + { + if (comma) + { + char *filepath = comma + 1; + + ret = grub_malloc (grub_strlen (filepath) + 1); + /* Make sure filepath has leading backslash. */ + if (filepath[0] != '\\') + grub_sprintf (ret, "\\%s", filepath); + else + grub_strcpy (ret, filepath); + } + } + else if (ptype == GRUB_PARSE_PARTITION) + { + if (!comma) + ret = grub_strdup (args); + else + ret = grub_strndup (args, (grub_size_t)(comma - args)); + } + } + else + { + /* XXX Handle net devices by configuring & registering a grub_net_dev + here, then return its name? + Example path: "net:,,,,,". */ + grub_printf ("Unsupported type %s for device %s\n", type, device); + } + +fail: + grub_free (device); + grub_free (args); + return ret; +} + +char * +grub_ieee1275_get_filename (const char *path) +{ + return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME); +} + +/* Convert a device name from IEEE1275 syntax to GRUB syntax. */ +char * +grub_ieee1275_encode_devname (const char *path) +{ + char *device = grub_ieee1275_get_devname (path); + char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); + char *encoding; + + if (partition) + { + unsigned int partno = grub_strtoul (partition, 0, 0); + + /* Assume partno will require less than five bytes to encode. */ + encoding = grub_malloc (grub_strlen (device) + 3 + 5); + grub_sprintf (encoding, "(%s,%d)", device, partno); + } + else + { + encoding = grub_malloc (grub_strlen (device) + 2); + grub_sprintf (encoding, "(%s)", device); + } + + grub_free (partition); + grub_free (device); + + return encoding; +} + +void +grub_reboot (void) +{ + grub_ieee1275_interpret ("reset-all", 0); +} + +void +grub_halt (void) +{ + grub_ieee1275_interpret ("power-off", 0); +} diff --git a/kern/term.c b/kern/term.c new file mode 100644 index 0000000..8d5a23b --- /dev/null +++ b/kern/term.c @@ -0,0 +1,331 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +/* The list of terminals. */ +static grub_term_input_t grub_term_list_input; +static grub_term_output_t grub_term_list_output; + +/* The current terminal. */ +static grub_term_input_t grub_cur_term_input; +static grub_term_output_t grub_cur_term_output; + +/* The amount of lines counted by the pager. */ +static int grub_more_lines; + +/* If the more pager is active. */ +static int grub_more; + +/* The current cursor state. */ +static int cursor_state = 1; + +void +grub_term_register_input (grub_term_input_t term) +{ + term->next = grub_term_list_input; + grub_term_list_input = term; + if (! grub_cur_term_input) + grub_term_set_current_input (term); +} + +void +grub_term_register_output (grub_term_output_t term) +{ + term->next = grub_term_list_output; + grub_term_list_output = term; + if (! grub_cur_term_output) + grub_term_set_current_output (term); +} + +void +grub_term_unregister_input (grub_term_input_t term) +{ + grub_term_input_t *p, q; + + for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next) + if (q == term) + { + *p = q->next; + break; + } +} + +void +grub_term_unregister_output (grub_term_output_t term) +{ + grub_term_output_t *p, q; + + for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next) + if (q == term) + { + *p = q->next; + break; + } +} + +void +grub_term_iterate_input (int (*hook) (grub_term_input_t term)) +{ + grub_term_input_t p; + + for (p = grub_term_list_input; p; p = p->next) + if (hook (p)) + break; +} + +void +grub_term_iterate_output (int (*hook) (grub_term_output_t term)) +{ + grub_term_output_t p; + + for (p = grub_term_list_output; p; p = p->next) + if (hook (p)) + break; +} + +grub_err_t +grub_term_set_current_input (grub_term_input_t term) +{ + if (grub_cur_term_input && grub_cur_term_input->fini) + if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE) + return grub_errno; + + if (term->init) + if ((term->init) () != GRUB_ERR_NONE) + return grub_errno; + + grub_cur_term_input = term; + return GRUB_ERR_NONE; +} + +grub_err_t +grub_term_set_current_output (grub_term_output_t term) +{ + if (grub_cur_term_output && grub_cur_term_output->fini) + if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE) + return grub_errno; + + if (term->init) + if ((term->init) () != GRUB_ERR_NONE) + return grub_errno; + + grub_cur_term_output = term; + return GRUB_ERR_NONE; +} + +grub_term_input_t +grub_term_get_current_input (void) +{ + return grub_cur_term_input; +} + +grub_term_output_t +grub_term_get_current_output (void) +{ + return grub_cur_term_output; +} + +/* Put a Unicode character. */ +void +grub_putcode (grub_uint32_t code) +{ + int height = grub_getwh () & 255; + + if (code == '\t' && grub_cur_term_output->getxy) + { + int n; + + n = 8 - ((grub_getxy () >> 8) & 7); + while (n--) + grub_putcode (' '); + + return; + } + + (grub_cur_term_output->putchar) (code); + + if (code == '\n') + { + grub_putcode ('\r'); + + grub_more_lines++; + + if (grub_more && grub_more_lines == height - 1) + { + char key; + int pos = grub_getxy (); + + /* Show --MORE-- on the lower left side of the screen. */ + grub_gotoxy (1, height - 1); + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("--MORE--"); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + + key = grub_getkey (); + + /* Remove the message. */ + grub_gotoxy (1, height - 1); + grub_printf (" "); + grub_gotoxy (pos >> 8, pos & 0xFF); + + /* Scroll one lines or an entire page, depending on the key. */ + if (key == '\r' || key =='\n') + grub_more_lines--; + else + grub_more_lines = 0; + } + } +} + +/* Put a character. C is one byte of a UTF-8 stream. + This function gathers bytes until a valid Unicode character is found. */ +void +grub_putchar (int c) +{ + static grub_size_t size = 0; + static grub_uint8_t buf[6]; + grub_uint32_t code; + grub_ssize_t ret; + + buf[size++] = c; + ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0); + + if (ret > 0) + { + size = 0; + grub_putcode (code); + } + else if (ret < 0) + { + size = 0; + grub_putcode ('?'); + } +} + +/* Return the number of columns occupied by the character code CODE. */ +grub_ssize_t +grub_getcharwidth (grub_uint32_t code) +{ + return (grub_cur_term_output->getcharwidth) (code); +} + +int +grub_getkey (void) +{ + return (grub_cur_term_input->getkey) (); +} + +int +grub_checkkey (void) +{ + return (grub_cur_term_input->checkkey) (); +} + +grub_uint16_t +grub_getxy (void) +{ + return (grub_cur_term_output->getxy) (); +} + +grub_uint16_t +grub_getwh (void) +{ + return (grub_cur_term_output->getwh) (); +} + +void +grub_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + (grub_cur_term_output->gotoxy) (x, y); +} + +void +grub_cls (void) +{ + if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) + { + grub_putchar ('\n'); + grub_refresh (); + } + else + (grub_cur_term_output->cls) (); +} + +void +grub_setcolorstate (grub_term_color_state state) +{ + if (grub_cur_term_output->setcolorstate) + (grub_cur_term_output->setcolorstate) (state); +} + +void +grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +{ + if (grub_cur_term_output->setcolor) + (grub_cur_term_output->setcolor) (normal_color, highlight_color); +} + +void +grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +{ + if (grub_cur_term_output->getcolor) + (grub_cur_term_output->getcolor) (normal_color, highlight_color); +} + +int +grub_setcursor (int on) +{ + int ret = cursor_state; + + if (grub_cur_term_output->setcursor) + { + (grub_cur_term_output->setcursor) (on); + cursor_state = on; + } + + return ret; +} + +int +grub_getcursor (void) +{ + return cursor_state; +} + +void +grub_refresh (void) +{ + if (grub_cur_term_output->refresh) + (grub_cur_term_output->refresh) (); +} + +void +grub_set_more (int onoff) +{ + if (onoff == 1) + grub_more++; + else + grub_more--; + + grub_more_lines = 0; +} diff --git a/kern/time.c b/kern/time.c new file mode 100644 index 0000000..6521ec6 --- /dev/null +++ b/kern/time.c @@ -0,0 +1,37 @@ +/* time.c - kernel time functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +typedef grub_uint64_t (*get_time_ms_func_t) (void); + +/* Function pointer to the implementation in use. */ +static get_time_ms_func_t get_time_ms_func; + +grub_uint64_t +grub_get_time_ms (void) +{ + return get_time_ms_func (); +} + +void +grub_install_get_time_ms (get_time_ms_func_t func) +{ + get_time_ms_func = func; +} diff --git a/kern/x86_64/dl.c b/kern/x86_64/dl.c new file mode 100644 index 0000000..bef3270 --- /dev/null +++ b/kern/x86_64/dl.c @@ -0,0 +1,121 @@ +/* dl-x86_64.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf64_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_X86_64) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf64_Ehdr *e = ehdr; + Elf64_Shdr *s; + Elf64_Sym *symtab; + Elf64_Word entsize; + unsigned i; + + /* Find a symbol table. */ + for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + symtab = (Elf64_Sym *) ((char *) e + s->sh_offset); + entsize = s->sh_entsize; + + for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + Elf64_Rela *rel, *max; + + for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + { + Elf64_Word *addr32; + Elf64_Xword *addr64; + Elf64_Sym *sym; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); + addr64 = (Elf64_Xword *) addr32; + sym = (Elf64_Sym *) ((char *) symtab + + entsize * ELF64_R_SYM (rel->r_info)); + + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_X86_64_64: + *addr64 = rel->r_addend + sym->st_value; + break; + + case R_X86_64_PC32: + *addr32 = rel->r_addend + sym->st_value - + (Elf64_Xword) seg->addr - rel->r_offset; + break; + + case R_X86_64_32: + case R_X86_64_32S: + *addr32 = rel->r_addend + sym->st_value; + break; + + default: + grub_fatal ("Unrecognized relocation: %d\n", ELF64_R_TYPE (rel->r_info)); + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/x86_64/efi/callwrap.S b/kern/x86_64/efi/callwrap.S new file mode 100644 index 0000000..6c390ec --- /dev/null +++ b/kern/x86_64/efi/callwrap.S @@ -0,0 +1,96 @@ +/* callwrap.S - wrapper for x86_64 efi calls */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +/* + * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use + * different call conversion, so we need to do some conversion. + * + * gcc: + * %rdi, %esi, %rdx, %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ... + * + * efi: + * %rcx, %rdx, %r8, %r9, 32(%rsp), 40(%rsp), 48(%rsp), ... + * + */ + + .file "callwrap.S" + .text + +FUNCTION(efi_wrap_0) + subq $40, %rsp + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_1) + subq $40, %rsp + mov %rsi, %rcx + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_2) + subq $40, %rsp + mov %rsi, %rcx + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_3) + subq $40, %rsp + mov %rcx, %r8 + mov %rsi, %rcx + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_4) + subq $40, %rsp + mov %r8, %r9 + mov %rcx, %r8 + mov %rsi, %rcx + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_5) + subq $40, %rsp + mov %r9, 32(%rsp) + mov %r8, %r9 + mov %rcx, %r8 + mov %rsi, %rcx + call *%rdi + addq $40, %rsp + ret + +FUNCTION(efi_wrap_6) + subq $56, %rsp + mov 56+8(%rsp), %rax + mov %rax, 40(%rsp) + mov %r9, (%rsp) + mov %r8, %r9 + mov %rcx, %r8 + mov %rsi, %rcx + call *%rdi + addq $56, %rsp + ret diff --git a/kern/x86_64/efi/startup.S b/kern/x86_64/efi/startup.S new file mode 100644 index 0000000..2fa6766 --- /dev/null +++ b/kern/x86_64/efi/startup.S @@ -0,0 +1,87 @@ +/* startup.S - bootstrap GRUB itself */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + + .file "startup.S" + .text + .globl start, _start + .code64 + +start: +_start: + jmp codestart + + /* + * Compatibility version number + * + * These MUST be at byte offset 6 and 7 of the executable + * DO NOT MOVE !!! + */ + . = EXT_C(start) + 0x6 + .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR + + /* + * This is a special data area 8 bytes from the beginning. + */ + + . = EXT_C(start) + 0x8 + +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = EXT_C(start) + 0x50 + +codestart: + + movq %rcx, EXT_C(grub_efi_image_handle) + movq %rdx, EXT_C(grub_efi_system_table) + + call EXT_C(grub_main) + ret + + .code32 + +FUNCTION(grub_linux_real_boot) + /* Turn off PG bit in CR0 and set CR3 to zero. */ + movl %cr0, %eax + andl $0x7FFFFFFF, %eax + movl %eax, %cr0 + + /* Setup EFER (Extended Feature Enable Register). */ + movl $0xc0000080, %ecx + rdmsr + + /* Disable Long Mode. */ + andl $0xFFFFFEFF, %eax + + /* Make changes effective. */ + wrmsr + + /* Disable PAE. */ + xorl %eax, %eax + movl %eax, %cr4 + + jmp *%ebx diff --git a/lib/LzFind.c b/lib/LzFind.c new file mode 100644 index 0000000..cd7a1cb --- /dev/null +++ b/lib/LzFind.c @@ -0,0 +1,774 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#include + +#include +#include + +#define kEmptyHashValue 0 +#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ +#define kNormalizeMask (~(kNormalizeStepMin - 1)) +#define kMaxHistorySize ((UInt32)3 << 30) + +#define kStartMaxLen 3 + +static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + if (!p->directInput) + { + alloc->Free(alloc, p->bufferBase); + p->bufferBase = 0; + } +} + +/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ + +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +{ + UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; + if (p->directInput) + { + p->blockSize = blockSize; + return 1; + } + if (p->bufferBase == 0 || p->blockSize != blockSize) + { + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); + } + return (p->bufferBase != 0); +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } + +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ + p->posLimit -= subValue; + p->pos -= subValue; + p->streamPos -= subValue; +} + +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + for (;;) + { + Byte *dest = p->buffer + (p->streamPos - p->pos); + size_t size = (p->bufferBase + p->blockSize - dest); + if (size == 0) + return; + p->result = p->stream->Read(p->stream, dest, &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (p->streamPos - p->pos > p->keepSizeAfter) + return; + } +} + +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + memmove(p->bufferBase, + p->buffer - p->keepSizeBefore, + (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); + p->buffer = p->bufferBase + p->keepSizeBefore; +} + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + /* if (p->streamEndWasReached) return 0; */ + return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->streamEndWasReached) + return; + if (p->keepSizeAfter >= p->streamPos - p->pos) + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +{ + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + /* p->skipModeBits = 0; */ + p->directInput = 0; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + UInt32 i; + p->bufferBase = 0; + p->directInput = 0; + p->hash = 0; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + p->crc[i] = r; + } +} + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->hash); + p->hash = 0; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +{ + size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return 0; + return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); +} + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc) +{ + UInt32 sizeReserv; + if (historySize > kMaxHistorySize) + { + MatchFinder_Free(p, alloc); + return 0; + } + sizeReserv = historySize >> 1; + if (historySize > ((UInt32)2 << 30)) + sizeReserv = historySize >> 2; + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); + + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1; + UInt32 hs; + p->matchMaxLen = matchMaxLen; + { + p->fixedHashSize = 0; + if (p->numHashBytes == 2) + hs = (1 << 16) - 1; + else + { + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + /* hs >>= p->skipModeBits; */ + hs |= 0xFFFF; /* don't change it! It's required for Deflate */ + if (hs > (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + } + } + p->hashMask = hs; + hs++; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + hs += p->fixedHashSize; + } + + { + UInt32 prevSize = p->hashSizeSum + p->numSons; + UInt32 newSize; + p->historySize = historySize; + p->hashSizeSum = hs; + p->cyclicBufferSize = newCyclicBufferSize; + p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); + newSize = p->hashSizeSum + p->numSons; + if (p->hash != 0 && prevSize == newSize) + return 1; + MatchFinder_FreeThisClassMemory(p, alloc); + p->hash = AllocRefs(newSize, alloc); + if (p->hash != 0) + { + p->son = p->hash + p->hashSizeSum; + return 1; + } + } + } + MatchFinder_Free(p, alloc); + return 0; +} + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 limit = kMaxValForNormalize - p->pos; + UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; + if (limit2 < limit) + limit = limit2; + limit2 = p->streamPos - p->pos; + if (limit2 <= p->keepSizeAfter) + { + if (limit2 > 0) + limit2 = 1; + } + else + limit2 -= p->keepSizeAfter; + if (limit2 < limit) + limit = limit2; + { + UInt32 lenLimit = p->streamPos - p->pos; + if (lenLimit > p->matchMaxLen) + lenLimit = p->matchMaxLen; + p->lenLimit = lenLimit; + } + p->posLimit = p->pos + limit; +} + +void MatchFinder_Init(CMatchFinder *p) +{ + UInt32 i; + for(i = 0; i < p->hashSizeSum; i++) + p->hash[i] = kEmptyHashValue; + p->cyclicBufferPos = 0; + p->buffer = p->bufferBase; + p->pos = p->streamPos = p->cyclicBufferSize; + p->result = SZ_OK; + p->streamEndWasReached = 0; + MatchFinder_ReadBlock(p); + MatchFinder_SetLimits(p); +} + +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +{ + return (p->pos - p->historySize - 1) & kNormalizeMask; +} + +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +{ + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } +} + +static void MatchFinder_Normalize(CMatchFinder *p) +{ + UInt32 subValue = MatchFinder_GetSubValue(p); + MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); + MatchFinder_ReduceOffsets(p, subValue); +} + +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (p->pos == kMaxValForNormalize) + MatchFinder_Normalize(p); + if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) + MatchFinder_CheckAndMoveAndRead(p); + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + MatchFinder_SetLimits(p); +} + +static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return distances; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + return distances; + } + } + } + } +} + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return distances; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return distances; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +#define MOVE_POS \ + ++p->cyclicBufferPos; \ + p->buffer++; \ + if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + +#define MOVE_POS_RET MOVE_POS return offset; + +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ + lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define GET_MATCHES_FOOTER(offset, maxLen) \ + offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ + distances + offset, maxLen) - distances); MOVE_POS_RET; + +#define SKIP_FOOTER \ + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; + +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 1) +} + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 2) +} + +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, delta2, maxLen, offset; + GET_MATCHES_HEADER(3) + + HASH3_CALC; + + delta2 = p->pos - p->hash[hash2Value]; + curMatch = p->hash[kFix3HashSize + hashValue]; + + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + + + maxLen = 2; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[0] = maxLen; + distances[1] = delta2 - 1; + offset = 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} + +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances, 2) - (distances)); + MOVE_POS_RET +} + +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value; + SKIP_HEADER(3) + HASH3_CALC; + curMatch = p->hash[kFix3HashSize + hashValue]; + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = p->pos; + p->hash[kFix4HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinder_Init; + vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + } + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + } +} diff --git a/lib/LzmaDec.c b/lib/LzmaDec.c new file mode 100644 index 0000000..62ebee6 --- /dev/null +++ b/lib/LzmaDec.c @@ -0,0 +1,1035 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#include + +#include + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ + { UPDATE_0(p); i = (i + i); A0; } else \ + { UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ + { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ + { i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; code -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ + { UPDATE_0_CHECK; i = (i + i); A0; } else \ + { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ + { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +/* +#define LZMA_STREAM_WAS_FINISHED_ID (-1) +#define LZMA_SPEC_LEN_OFFSET (-3) +*/ + +Byte kLiteralNextStates[kNumStates * 2] = +{ + 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, + 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 +}; + +#define LZMA_DIC_MIN (1 << 12) + +/* First LZMA-symbol is always decoded. +And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization +Out: + Result: + 0 - OK + 1 - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker +*/ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + CLzmaProb *probs = p->probs; + + unsigned state = p->state; + UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + Byte *dic = p->dic; + SizeT dicBufSize = p->dicBufSize; + SizeT dicPos = p->dicPos; + + UInt32 processedPos = p->processedPos; + UInt32 checkDicSize = p->checkDicSize; + unsigned len = 0; + + const Byte *buf = p->buf; + UInt32 range = p->range; + UInt32 code = p->code; + + do + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); + + if (state < kNumLitStates) + { + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (Byte)symbol; + processedPos++; + + state = kLiteralNextStates[state]; + /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ + continue; + } + else + { + UPDATE_1(prob); + prob = probs + IsRep + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0(prob) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + UPDATE_1(prob); + } + else + { + UInt32 distance; + UPDATE_1(prob); + prob = probs + IsRepG1 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + UPDATE_1(prob); + prob = probs + IsRepG2 + state; + IF_BIT_0(prob) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = (1 << kLenNumLowBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenChoice2; + IF_BIT_0(probLen) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = (1 << kLenNumMidBits); + } + else + { + UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, limit, len); + len += offset; + } + + if (state >= kNumStates) + { + UInt32 distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + UInt32 mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while(--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE + range >>= 1; + + { + UInt32 t; + code -= range; + t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ + distance = (distance << 1) + (t + 1); + code += range & t; + } + /* + distance <<= 1; + if (code >= range) + { + code -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (UInt32)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + /* state = kLiteralNextStates[state]; */ + } + + len += kMatchMinLen; + + { + SizeT rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + Byte *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const Byte *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (Byte)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + } + while (dicPos < limit && buf < bufLimit); + NORMALIZE; + p->buf = buf; + p->range = range; + p->code = code; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + Byte *dic = p->dic; + SizeT dicPos = p->dicPos; + SizeT dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + UInt32 rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */ + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +{ + do + { + SizeT limit2 = limit; + if (p->checkDicSize == 0) + { + UInt32 rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +{ + UInt32 range = p->range; + UInt32 code = p->code; + const Byte *bufLimit = buf + inSize; + CLzmaProb *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + CLzmaProb *prob; + UInt32 bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchByte = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + CLzmaProb *probLit; + matchByte <<= 1; + bit = (matchByte & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + CLzmaProb *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + code -= range & (((code - range) >> 31) - 1); + /* if (code >= range) code -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while(--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +{ + p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, True, True); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + UInt32 i; + CLzmaProb *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + SizeT processed; + const Byte *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = p->buf - src; + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + SizeT outSize = *destLen; + SizeT inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + SizeT inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +{ + UInt32 dicSize; + Byte d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + UInt32 numProbs = LzmaProps_GetNumProbs(propNew); + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + SizeT inSize = *srcLen; + SizeT outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/lib/LzmaEnc.c b/lib/LzmaEnc.c new file mode 100644 index 0000000..842d43a --- /dev/null +++ b/lib/LzmaEnc.c @@ -0,0 +1,2355 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#include +#include + +#include + +#include +#ifdef COMPRESS_MF_MT +#include +#endif + +/* #define SHOW_STAT */ +/* #define SHOW_STAT2 */ + +#ifdef SHOW_STAT +static int ttt = 0; +#endif + +#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) + +#define kBlockSize (9 << 10) +#define kUnpackBlockSize (1 << 18) +#define kMatchArraySize (1 << 21) +#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) + +#define kNumMaxDirectBits (31) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); + if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1); +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +/* #define LZMA_LOG_BSR */ +/* Define it for Intel's CPU */ + + +#ifdef LZMA_LOG_BSR + +#define kDicLogSizeMaxCompress 30 + +#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } + +UInt32 GetPosSlot1(UInt32 pos) +{ + UInt32 res; + BSR2_RET(pos, res); + return res; +} +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } + +#else + +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + UInt32 j; + for (j = 0; j < k; j++, c++) + g_FastPos[c] = (Byte)slotFast; + } +} + +#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> i] + (i * 2); } +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } + +#endif + + +#define LZMA_NUM_REPS 4 + +typedef unsigned CState; + +typedef struct _COptimal +{ + UInt32 price; + + CState state; + int prev1IsChar; + int prev2; + + UInt32 posPrev2; + UInt32 backPrev2; + + UInt32 posPrev; + UInt32 backPrev; + UInt32 backs[LZMA_NUM_REPS]; +} COptimal; + +#define kNumOpts (1 << 12) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) + +#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + +typedef struct +{ + CLzmaProb choice; + CLzmaProb choice2; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; + CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + +typedef struct +{ + CLenEnc p; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + UInt32 tableSize; + UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +} CLenPriceEnc; + +typedef struct _CRangeEnc +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct _CSeqInStreamBuf +{ + ISeqInStream funcTable; + const Byte *data; + SizeT rem; +} CSeqInStreamBuf; + +static SRes MyRead(void *pp, void *data, size_t *size) +{ + size_t curSize = *size; + CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; + if (p->rem < curSize) + curSize = p->rem; + memcpy(data, p->data, curSize); + p->rem -= curSize; + p->data += curSize; + *size = curSize; + return SZ_OK; +} + +typedef struct +{ + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; +} CSaveState; + +typedef struct _CLzmaEnc +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + #ifdef COMPRESS_MF_MT + Bool mtMode; + CMatchFinderMt matchFinderMt; + #endif + + CMatchFinder matchFinderBase; + + #ifdef COMPRESS_MF_MT + Byte pad[128]; + #endif + + UInt32 optimumEndIndex; + UInt32 optimumCurrentIndex; + + Bool longestMatchWasFound; + UInt32 longestMatchLength; + UInt32 numDistancePairs; + + COptimal opt[kNumOpts]; + + #ifndef LZMA_LOG_BSR + Byte g_FastPos[1 << kNumLogBits]; + #endif + + UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + UInt32 numFastBytes; + UInt32 additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; + + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 alignPrices[kAlignTableSize]; + UInt32 alignPriceCount; + + UInt32 distTableSize; + + unsigned lc, lp, pb; + unsigned lpMask, pbMask; + + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + unsigned lclp; + + Bool fastMode; + + CRangeEnc rc; + + Bool writeEndMark; + UInt64 nowPos64; + UInt32 matchPriceCount; + Bool finished; + Bool multiThread; + + SRes result; + UInt32 dictSize; + UInt32 matchFinderCycles; + + ISeqInStream *inStream; + CSeqInStreamBuf seqBufInStream; + + CSaveState saveState; +} CLzmaEnc; + +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + +void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +} + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || + props.dictSize > (1U << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) + return SZ_ERROR_PARAM; + p->dictSize = props.dictSize; + p->matchFinderCycles = props.mc; + { + unsigned fb = props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = props.lc; + p->lp = props.lp; + p->pb = props.pb; + p->fastMode = (props.algo == 0); + p->matchFinderBase.btMode = props.btMode; + { + UInt32 numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = props.numHashBytes; + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = props.writeEndMark; + + #ifdef COMPRESS_MF_MT + /* + if (newMultiThread != _multiThread) + { + ReleaseMatchFinder(); + _multiThread = newMultiThread; + } + */ + p->multiThread = (props.numThreads > 1); + #endif + + return SZ_OK; +} + +static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +/* + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } +*/ + +#define IsCharState(s) ((s) < 7) + + +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = 0; + p->bufBase = 0; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +{ + if (p->bufBase == 0) + { + p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + if (p->bufBase == 0) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->low = 0; + p->range = 0xFFFFFFFF; + p->cacheSize = 1; + p->cache = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = p->buf - p->bufBase; + if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + { + Byte temp = p->cache; + do + { + Byte *buf = p->buf; + *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + temp = 0xFF; + } + while (--p->cacheSize != 0); + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +{ + do + { + p->range >>= 1; + p->low += p->range & (0 - ((value >> --numBits) & 1)); + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } + } + while (numBits != 0); +} + +static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +{ + UInt32 ttt = *prob; + UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; + if (symbol == 0) + { + p->range = newBound; + ttt += (kBitModelTotal - ttt) >> kNumMoveBits; + } + else + { + p->low += newBound; + p->range -= newBound; + ttt -= ttt >> kNumMoveBits; + } + *prob = (CLzmaProb)ttt; + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +{ + symbol |= 0x100; + do + { + RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +{ + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); +} + +void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) + { + const int kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = i; + UInt32 bitCount = 0; + int j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + } +} + + +#define GET_PRICE(prob, symbol) \ + p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, symbol) \ + ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= 0x100; + do + { + price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); + return price; +}; + +static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); + return price; +}; + + +static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0 ;) + { + UInt32 bit; + i--; + bit = (symbol >> i) & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + } +}; + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = 0; i < numBitLevels; i++) + { + UInt32 bit = symbol & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } +} + +static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= (1 << numBitLevels); + while (symbol != 1) + { + price += GET_PRICEa(probs[symbol >> 1], symbol & 1); + symbol >>= 1; + } + return price; +} + +static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) | bit; + } + return price; +} + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + p->choice = p->choice2 = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) + p->mid[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +{ + if (symbol < kLenNumLowSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice, 0); + RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice, 1); + if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice2, 0); + RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice2, 1); + RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); + } + } +} + +static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +{ + UInt32 a0 = GET_PRICE_0a(p->choice); + UInt32 a1 = GET_PRICE_1a(p->choice); + UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); + UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); + UInt32 i = 0; + for (i = 0; i < kLenNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); + } + for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); + } + for (; i < numSymbols; i++) + prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +} + +static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +{ + LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); + p->counters[posState] = p->tableSize; +} + +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +{ + UInt32 posState; + for (posState = 0; posState < numPosStates; posState++) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + +static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +{ + LenEnc_Encode(&p->p, rc, symbol, posState); + if (updatePrice) + if (--p->counters[posState] == 0) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + + + + +static void MovePos(CLzmaEnc *p, UInt32 num) +{ + #ifdef SHOW_STAT + ttt += num; + printf("\n MovePos %d", num); + #endif + if (num != 0) + { + p->additionalOffset += num; + p->matchFinder.Skip(p->matchFinderObj, num); + } +} + +static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +{ + UInt32 lenRes = 0, numDistancePairs; + numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances); + #ifdef SHOW_STAT + printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2); + if (ttt >= 61994) + ttt = ttt; + + ttt++; + { + UInt32 i; + for (i = 0; i < numDistancePairs; i += 2) + printf("%2d %6d | ", p->matchDistances[i], p->matchDistances[i + 1]); + } + #endif + if (numDistancePairs > 0) + { + lenRes = p->matchDistances[numDistancePairs - 2]; + if (lenRes == p->numFastBytes) + { + UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1; + const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + { + const Byte *pby2 = pby - distance; + for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); + } + } + } + p->additionalOffset++; + *numDistancePairsRes = numDistancePairs; + return lenRes; +} + + +#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +#define IsShortRep(p) ((p)->backPrev == 0) + +static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +{ + return + GET_PRICE_0(p->isRepG0[state]) + + GET_PRICE_0(p->isRep0Long[state][posState]); +} + +static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +{ + UInt32 price; + if (repIndex == 0) + { + price = GET_PRICE_0(p->isRepG0[state]); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(p->isRepG0[state]); + if (repIndex == 1) + price += GET_PRICE_0(p->isRepG1[state]); + else + { + price += GET_PRICE_1(p->isRepG1[state]); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + +static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +{ + return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + GetPureRepPrice(p, repIndex, state, posState); +} + +static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +{ + UInt32 posMem = p->opt[cur].posPrev; + UInt32 backMem = p->opt[cur].backPrev; + p->optimumEndIndex = cur; + do + { + if (p->opt[cur].prev1IsChar) + { + MakeAsChar(&p->opt[posMem]) + p->opt[posMem].posPrev = posMem - 1; + if (p->opt[cur].prev2) + { + p->opt[posMem - 1].prev1IsChar = False; + p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + } + } + { + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = p->opt[posPrev].backPrev; + posMem = p->opt[posPrev].posPrev; + + p->opt[posPrev].backPrev = backCur; + p->opt[posPrev].posPrev = cur; + cur = posPrev; + } + } + while (cur != 0); + *backRes = p->opt[0].backPrev; + p->optimumCurrentIndex = p->opt[0].posPrev; + return p->optimumCurrentIndex; +} + +#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) + +static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +{ + UInt32 numAvailableBytes, lenMain, numDistancePairs; + const Byte *data; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 matchPrice, repMatchPrice; + UInt32 lenEnd; + UInt32 len; + UInt32 normalMatchPrice; + UInt32 cur; + if (p->optimumEndIndex != p->optimumCurrentIndex) + { + const COptimal *opt = &p->opt[p->optimumCurrentIndex]; + UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; + *backRes = opt->backPrev; + p->optimumCurrentIndex = opt->posPrev; + return lenRes; + } + p->optimumCurrentIndex = p->optimumEndIndex = 0; + + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + + repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 lenTest; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - (reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= p->numFastBytes) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + *backRes = (UInt32)-1; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsCharState(p->state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + MakeAsChar(&p->opt[1]); + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + if (matchByte == currentByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAsShortRep(&p->opt[1]); + } + } + lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + *backRes = p->opt[1].backPrev; + return 1; + } + + p->opt[1].posPrev = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + p->opt[0].backs[i] = reps[i]; + + len = lenEnd; + do + p->opt[len--].price = kInfinityPrice; + while (len >= 2); + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; + COptimal *opt = &p->opt[repLen]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = i; + opt->prev1IsChar = False; + } + } + while (--repLen >= 2); + } + + normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + UInt32 offs = 0; + while (len > matchDistances[offs]) + offs += 2; + for (; ; len++) + { + COptimal *opt; + UInt32 distance = matchDistances[offs + 1]; + + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(len); + if (distance < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][distance]; + else + { + UInt32 slot; + GetPosSlot2(distance, slot); + curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; + } + opt = &p->opt[len]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = distance + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + if (len == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + cur = 0; + + #ifdef SHOW_STAT2 + if (position >= 0) + { + unsigned i; + printf("\n pos = %4X", position); + for (i = cur; i <= lenEnd; i++) + printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); + } + #endif + + for (;;) + { + UInt32 numAvailableBytesFull, newLen, numDistancePairs; + COptimal *curOpt; + UInt32 posPrev; + UInt32 state; + UInt32 curPrice; + Bool nextIsChar; + const Byte *data; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 curAnd1Price; + COptimal *nextOpt; + UInt32 matchPrice, repMatchPrice; + UInt32 numAvailableBytes; + UInt32 startLen; + + cur++; + if (cur == lenEnd) + return Backward(p, backRes, cur); + + numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + newLen = ReadMatchDistances(p, &numDistancePairs); + if (newLen >= p->numFastBytes) + { + p->numDistancePairs = numDistancePairs; + p->longestMatchLength = newLen; + p->longestMatchWasFound = True; + return Backward(p, backRes, cur); + } + position++; + curOpt = &p->opt[cur]; + posPrev = curOpt->posPrev; + if (curOpt->prev1IsChar) + { + posPrev--; + if (curOpt->prev2) + { + state = p->opt[curOpt->posPrev2].state; + if (curOpt->backPrev2 < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + else + state = p->opt[posPrev].state; + state = kLiteralNextStates[state]; + } + else + state = p->opt[posPrev].state; + if (posPrev == cur - 1) + { + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + UInt32 pos; + const COptimal *prevOpt; + if (curOpt->prev1IsChar && curOpt->prev2) + { + posPrev = curOpt->posPrev2; + pos = curOpt->backPrev2; + state = kRepNextStates[state]; + } + else + { + pos = curOpt->backPrev; + if (pos < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + prevOpt = &p->opt[posPrev]; + if (pos < LZMA_NUM_REPS) + { + UInt32 i; + reps[0] = prevOpt->backs[pos]; + for (i = 1; i <= pos; i++) + reps[i] = prevOpt->backs[i - 1]; + for (; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i]; + } + else + { + UInt32 i; + reps[0] = (pos - LZMA_NUM_REPS); + for (i = 1; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i - 1]; + } + } + curOpt->state = (CState)state; + + curOpt->backs[0] = reps[0]; + curOpt->backs[1] = reps[1]; + curOpt->backs[2] = reps[2]; + curOpt->backs[3] = reps[3]; + + curPrice = curOpt->price; + nextIsChar = False; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + posState = (position & p->pbMask); + + curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + curAnd1Price += + (!IsCharState(state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + nextOpt = &p->opt[cur + 1]; + + if (curAnd1Price < nextOpt->price) + { + nextOpt->price = curAnd1Price; + nextOpt->posPrev = cur; + MakeAsChar(nextOpt); + nextIsChar = True; + } + + matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); + if (shortRepPrice <= nextOpt->price) + { + nextOpt->price = shortRepPrice; + nextOpt->posPrev = cur; + MakeAsShortRep(nextOpt); + nextIsChar = True; + } + } + + { + UInt32 temp = kNumOpts - 1 - cur; + if (temp < numAvailableBytesFull) + numAvailableBytesFull = temp; + } + numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > p->numFastBytes) + numAvailableBytes = p->numFastBytes; + if (!nextIsChar && matchByte != currentByte) /* speed optimization */ + { + /* try Literal + rep0 */ + UInt32 temp; + UInt32 lenTest2; + const Byte *data2 = data - (reps[0] + 1); + UInt32 limit = p->numFastBytes + 1; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + + for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); + lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kLiteralNextStates[state]; + UInt32 posStateNext = (position + 1) & p->pbMask; + UInt32 nextRepMatchPrice = curAnd1Price + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = False; + } + } + } + } + + startLen = 2; /* speed optimization */ + { + UInt32 repIndex; + for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) + { + UInt32 lenTest; + UInt32 lenTestTemp; + UInt32 price; + const Byte *data2 = data - (reps[repIndex] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + while (lenEnd < cur + lenTest) + p->opt[++lenEnd].price = kInfinityPrice; + lenTestTemp = lenTest; + price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + COptimal *opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = repIndex; + opt->prev1IsChar = False; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + /* if (_maxMode) */ + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kRepNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = + price + p->repLenEnc.prices[posState][lenTest - 2] + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (position + lenTest + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + lenTest + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = repIndex; + } + } + } + } + } + } + /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); + matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 offs, curBack, posSlot; + UInt32 lenTest; + while (lenEnd < cur + newLen) + p->opt[++lenEnd].price = kInfinityPrice; + + offs = 0; + while (startLen > matchDistances[offs]) + offs += 2; + curBack = matchDistances[offs + 1]; + GetPosSlot2(curBack, posSlot); + for (lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(lenTest); + COptimal *opt; + if (curBack < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + + opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = curBack + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + + if (/*_maxMode && */lenTest == matchDistances[offs]) + { + /* Try Match + Literal + Rep0 */ + const Byte *data2 = data - (curBack + 1); + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kMatchNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (posStateNext + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + UInt32 curAndLenPrice; + COptimal *opt; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = curBack + LZMA_NUM_REPS; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + curBack = matchDistances[offs + 1]; + if (curBack >= kNumFullDistances) + GetPosSlot2(curBack, posSlot); + } + } + } + } +} + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + +static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +{ + UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + UInt32 lenMain, numDistancePairs; + const Byte *data; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + UInt32 backMain; + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + + repMaxIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + const Byte *data2 = data - (p->reps[i] + 1); + UInt32 len; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len >= p->numFastBytes) + { + *backRes = i; + MovePos(p, len - 1); + return len; + } + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + + backMain = 0; /* for GCC */ + if (lenMain >= 2) + { + backMain = matchDistances[numDistancePairs - 1]; + while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) + { + if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) + break; + numDistancePairs -= 2; + lenMain = matchDistances[numDistancePairs - 2]; + backMain = matchDistances[numDistancePairs - 1]; + } + if (lenMain == 2 && backMain >= 0x80) + lenMain = 1; + } + + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) || + (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + } + + if (lenMain >= 2 && numAvailableBytes > 2) + { + UInt32 i; + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs); + if (p->longestMatchLength >= 2) + { + UInt32 newDistance = matchDistances[p->numDistancePairs - 1]; + if ((p->longestMatchLength >= lenMain && newDistance < backMain) || + (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) || + (p->longestMatchLength > lenMain + 1) || + (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[1] != data2[1] || data[2] != data2[2]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len + 1 >= lenMain) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + *backRes = backMain + LZMA_NUM_REPS; + MovePos(p, lenMain - 2); + return lenMain; + } + *backRes = (UInt32)(-1); + return 1; +} + +static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +{ + UInt32 len; + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + len = LZMA_MATCH_LEN_MIN; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); + RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +} + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + +static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + +static void FillAlignPrices(CLzmaEnc *p) +{ + UInt32 i; + for (i = 0; i < kAlignTableSize; i++) + p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + p->alignPriceCount = 0; +} + +static void FillDistancesPrices(CLzmaEnc *p) +{ + UInt32 tempPrices[kNumFullDistances]; + UInt32 i, lenToPosState; + for (i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot1(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); + } + + for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); + for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + + { + UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; + } + } + p->matchPriceCount = 0; +} + +void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + #ifdef COMPRESS_MF_MT + MatchFinderMt_Construct(&p->matchFinderMt); + p->matchFinderMt.MatchFinder = &p->matchFinderBase; + #endif + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + #ifndef LZMA_LOG_BSR + LzmaEnc_FastPosInit(p->g_FastPos); + #endif + + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +{ + void *p; + p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + if (p != 0) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + #ifdef COMPRESS_MF_MT + MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); + #endif + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + alloc->Free(alloc, p); +} + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->inStream != 0) + { + p->matchFinderBase.stream = p->inStream; + p->matchFinder.Init(p->matchFinderObj); + p->inStream = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + UInt32 numDistancePairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numDistancePairs); + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); + p->state = kLiteralNextStates[p->state]; + curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + for (;;) + { + UInt32 pos, len, posState; + + if (p->fastMode) + len = GetOptimumFast(p, &pos); + else + len = GetOptimum(p, nowPos32, &pos); + + #ifdef SHOW_STAT2 + printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); + #endif + + posState = nowPos32 & p->pbMask; + if (len == 1 && pos == 0xFFFFFFFF) + { + Byte curByte; + CLzmaProb *probs; + const Byte *data; + + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + curByte = *data; + probs = LIT_PROBS(nowPos32, *(data - 1)); + if (IsCharState(p->state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); + p->state = kLiteralNextStates[p->state]; + } + else + { + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + if (pos < LZMA_NUM_REPS) + { + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); + if (pos == 0) + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); + RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = p->reps[pos]; + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); + if (pos == 1) + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); + else + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); + if (pos == 3) + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = distance; + } + if (len == 1) + p->state = kShortRepNextStates[p->state]; + else + { + LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + p->state = kRepNextStates[p->state]; + } + } + else + { + UInt32 posSlot; + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + pos -= LZMA_NUM_REPS; + GetPosSlot(pos, posSlot); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); + else + { + RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + p->alignPriceCount++; + } + } + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = pos; + p->matchPriceCount++; + } + } + p->additionalOffset -= len; + nowPos32 += len; + if (p->additionalOffset == 0) + { + UInt32 processed; + if (!p->fastMode) + { + if (p->matchPriceCount >= (1 << 7)) + FillDistancesPrices(p); + if (p->alignPriceCount >= kAlignTableSize) + FillAlignPrices(p); + } + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + if (useLimits) + { + if (processed + kNumOpts + 300 >= maxUnpackSize || + RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) + break; + } + else if (processed >= (1 << 15)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 beforeSize = kNumOpts; + Bool btMode; + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + btMode = (p->matchFinderBase.btMode != 0); + #ifdef COMPRESS_MF_MT + p->mtMode = (p->multiThread && !p->fastMode && btMode); + #endif + + { + unsigned lclp = p->lc + p->lp; + if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + if (p->litProbs == 0 || p->saveState.litProbs == 0) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + #ifdef COMPRESS_MF_MT + if (p->mtMode) + { + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); + p->matchFinderObj = &p->matchFinderMt; + MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); + } + else + #endif + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + return SZ_OK; +} + +void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; + for(i = 0 ; i < LZMA_NUM_REPS; i++) + p->reps[i] = 0; + + RangeEnc_Init(&p->rc); + + + for (i = 0; i < kNumStates; i++) + { + UInt32 j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + UInt32 num = 0x300 << (p->lp + p->lc); + for (i = 0; i < num; i++) + p->litProbs[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + UInt32 j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + p->posEncoders[i] = kProbInitValue; + } + + LenEnc_Init(&p->lenEnc.p); + LenEnc_Init(&p->repLenEnc.p); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + p->longestMatchWasFound = False; + p->optimumEndIndex = 0; + p->optimumCurrentIndex = 0; + p->additionalOffset = 0; + + p->pbMask = (1 << p->pb) - 1; + p->lpMask = (1 << p->lp) - 1; +} + +void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 i; + for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->seqBufInStream.funcTable.Read = MyRead; + p->seqBufInStream.data = src; + p->seqBufInStream.rem = srcLen; +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->inStream = &p->seqBufInStream.funcTable; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + #ifdef COMPRESS_MF_MT + CLzmaEnc *p = (CLzmaEnc *)pp; + if (p->mtMode) + MatchFinderMt_ReleaseStream(&p->matchFinderMt); + #else + (void)pp; + #endif +} + +typedef struct _CSeqOutStreamBuf +{ + ISeqOutStream funcTable; + Byte *data; + SizeT rem; + Bool overflow; +} CSeqOutStreamBuf; + +static size_t MyWrite(void *pp, const void *data, size_t size) +{ + CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + + +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CSeqOutStreamBuf outStream; + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.funcTable; + + res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + SRes res = SZ_OK; + + #ifdef COMPRESS_MF_MT + Byte allocaDummy[0x300]; + int i = 0; + for (i = 0; i < 16; i++) + allocaDummy[i] = (Byte)i; + #endif + + RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); + + for (;;) + { + res = LzmaEnc_CodeOneBlock(pp, False, 0, 0); + if (res != SZ_OK || p->finished != 0) + break; + if (progress != 0) + { + res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + LzmaEnc_Finish(pp); + return res; +} + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + int i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) + { + dictSize = (2 << i); + break; + } + if (dictSize <= ((UInt32)3 << i)) + { + dictSize = (3 << i); + break; + } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CSeqOutStreamBuf outStream; + + LzmaEnc_SetInputBuf(p, src, srcLen); + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, + progress, alloc, allocBig); + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (p == 0) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} diff --git a/lib/crc.c b/lib/crc.c new file mode 100644 index 0000000..bc0d8aa --- /dev/null +++ b/lib/crc.c @@ -0,0 +1,75 @@ +/* crc.c - crc function */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +static grub_uint32_t crc32_table [256]; + +static void +init_crc32_table (void) +{ + auto grub_uint32_t reflect (grub_uint32_t ref, int len); + grub_uint32_t reflect (grub_uint32_t ref, int len) + { + grub_uint32_t result = 0; + int i; + + for (i = 1; i <= len; i++) + { + if (ref & 1) + result |= 1 << (len - i); + ref >>= 1; + } + + return result; + } + + grub_uint32_t polynomial = 0x04c11db7; + int i, j; + + for(i = 0; i < 256; i++) + { + crc32_table[i] = reflect(i, 8) << 24; + for (j = 0; j < 8; j++) + crc32_table[i] = (crc32_table[i] << 1) ^ + (crc32_table[i] & (1 << 31) ? polynomial : 0); + crc32_table[i] = reflect(crc32_table[i], 32); + } +} + +grub_uint32_t +grub_getcrc32 (grub_uint32_t crc, void *buf, int size) +{ + int i; + grub_uint8_t *data = buf; + + if (! crc32_table[1]) + init_crc32_table (); + + crc^= 0xffffffff; + + for (i = 0; i < size; i++) + { + crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data]; + data++; + } + + return crc ^ 0xffffffff; +} diff --git a/lib/datetime.c b/lib/datetime.c new file mode 100644 index 0000000..7215a6a --- /dev/null +++ b/lib/datetime.c @@ -0,0 +1,49 @@ +/* datetime.c - Module for common datetime function. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +static char *grub_weekday_names[] = +{ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", +}; + +int +grub_get_weekday (struct grub_datetime *datetime) +{ + int a, y, m; + + a = (14 - datetime->month) / 12; + y = datetime->year - a; + m = datetime->month + 12 * a - 2; + + return (datetime->day + y + y / 4 - y / 100 + y / 400 + (31 * m / 12)) % 7; +} + +char * +grub_get_weekday_name (struct grub_datetime *datetime) +{ + return grub_weekday_names[grub_get_weekday (datetime)]; +} diff --git a/lib/efi/datetime.c b/lib/efi/datetime.c new file mode 100644 index 0000000..9fa72fd --- /dev/null +++ b/lib/efi/datetime.c @@ -0,0 +1,79 @@ +/* kern/efi/datetime.c - efi datetime function. + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +grub_err_t +grub_get_datetime (struct grub_datetime *datetime) +{ + grub_efi_status_t status; + struct grub_efi_time efi_time; + + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, + &efi_time, 0); + + if (status) + return grub_error (GRUB_ERR_INVALID_COMMAND, + "can\'t get datetime using efi"); + else + { + datetime->year = efi_time.year; + datetime->month = efi_time.month; + datetime->day = efi_time.day; + datetime->hour = efi_time.hour; + datetime->minute = efi_time.minute; + datetime->second = efi_time.second; + } + + return 0; +} + +grub_err_t +grub_set_datetime (struct grub_datetime *datetime) +{ + grub_efi_status_t status; + struct grub_efi_time efi_time; + + status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, + &efi_time, 0); + + if (status) + return grub_error (GRUB_ERR_INVALID_COMMAND, + "can\'t get datetime using efi"); + + efi_time.year = datetime->year; + efi_time.month = datetime->month; + efi_time.day = datetime->day; + efi_time.hour = datetime->hour; + efi_time.minute = datetime->minute; + efi_time.second = datetime->second; + + status = efi_call_1 (grub_efi_system_table->runtime_services->set_time, + &efi_time); + + if (status) + return grub_error (GRUB_ERR_INVALID_COMMAND, + "can\'t set datetime using efi"); + + return 0; +} diff --git a/lib/envblk.c b/lib/envblk.c new file mode 100644 index 0000000..6618d97 --- /dev/null +++ b/lib/envblk.c @@ -0,0 +1,156 @@ +/* envblk.c - Common function for environment block. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_envblk_t +grub_envblk_find (char *buf) +{ + grub_uint32_t *pd; + int len; + + pd = (grub_uint32_t *) buf; + + for (len = GRUB_ENVBLK_MAXLEN - 6; len > 0; len -= 4, pd++) + if (*pd == GRUB_ENVBLK_SIGNATURE) + { + grub_envblk_t p; + + p = (grub_envblk_t) pd; + if (p->length <= len) + return p; + } + + return 0; +} + +int +grub_envblk_insert (grub_envblk_t envblk, char *name, char *value) +{ + char *p, *pend; + char *found = 0; + int nl; + + nl = grub_strlen (name); + p = envblk->data; + pend = p + envblk->length; + + while (*p) + { + if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '=')) + found = p + nl + 1; + + p += grub_strlen (p) + 1; + if (p >= pend) + return 1; + } + + if (found) + { + int len1, len2; + + len1 = grub_strlen (found); + len2 = grub_strlen (value); + if ((p - envblk->data) + 1 - len1 + len2 > envblk->length) + return 1; + + grub_memcpy (found + len2 + 1, found + len1 + 1, (p - found) - len1); + grub_strcpy (found, value); + } + else + { + int len2 = grub_strlen (value); + + if ((p - envblk->data) + nl + 1 + len2 + 2 > envblk->length) + return 1; + + grub_strcpy (p, name); + p[nl] = '='; + grub_strcpy (p + nl + 1, value); + p[nl + 1 + len2 + 1] = 0; + } + + return 0; +} + +void +grub_envblk_delete (grub_envblk_t envblk, char *name) +{ + char *p, *pend; + char *found = 0; + int nl; + + nl = grub_strlen (name); + p = envblk->data; + pend = p + envblk->length; + + while (*p) + { + if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '=')) + found = p; + + p += grub_strlen (p) + 1; + if (p >= pend) + return; + } + + if (found) + { + int len; + + len = grub_strlen (found); + grub_memcpy (found, found + len + 1, (p - found) - len); + } +} + +void +grub_envblk_iterate (grub_envblk_t envblk, + int hook (char *name, char *value)) +{ + char *p, *pend; + + p = envblk->data; + pend = p + envblk->length; + + while (*p) + { + char *v; + int r; + + v = grub_strchr (p, '='); + if (v) + { + *v = 0; + r = hook (p, v + 1); + *v = '='; + } + else + r = hook (p, ""); + + if (r) + break; + + p += grub_strlen (p) + 1; + if (p >= pend) + break; + } +} diff --git a/lib/hexdump.c b/lib/hexdump.c new file mode 100644 index 0000000..c69cb09 --- /dev/null +++ b/lib/hexdump.c @@ -0,0 +1,84 @@ +/* hexdump.c - hexdump function */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +void +hexdump (unsigned long bse, char *buf, int len) +{ + int pos; + char line[80]; + + while (len > 0) + { + int cnt, i; + + pos = grub_sprintf (line, "%08lx ", bse); + cnt = 16; + if (cnt > len) + cnt = len; + + for (i = 0; i < cnt; i++) + { + pos += grub_sprintf (&line[pos], "%02x ", (unsigned char) buf[i]); + if ((i & 7) == 7) + line[pos++] = ' '; + } + + for (; i < 16; i++) + { + pos += grub_sprintf (&line[pos], " "); + if ((i & 7) == 7) + line[pos++] = ' '; + } + + line[pos++] = '|'; + + for (i = 0; i < cnt; i++) + line[pos++] = ((buf[i] >= 32) && (buf[i] < 127)) ? buf[i] : '.'; + + line[pos++] = '|'; + + line[pos] = 0; + + grub_printf ("%s\n", line); + + /* Print only first and last line if more than 3 lines are identical. */ + if (len >= 4 * 16 + && ! grub_memcmp (buf, buf + 1 * 16, 16) + && ! grub_memcmp (buf, buf + 2 * 16, 16) + && ! grub_memcmp (buf, buf + 3 * 16, 16)) + { + grub_printf ("*\n"); + do + { + bse += 16; + buf += 16; + len -= 16; + } + while (len >= 3 * 16 && ! grub_memcmp (buf, buf + 2 * 16, 16)); + } + + bse += 16; + buf += 16; + len -= cnt; + } +} diff --git a/lib/i386/datetime.c b/lib/i386/datetime.c new file mode 100644 index 0000000..1e59746 --- /dev/null +++ b/lib/i386/datetime.c @@ -0,0 +1,155 @@ +/* kern/i386/datetime.c - x86 CMOS datetime function. + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +grub_err_t +grub_get_datetime (struct grub_datetime *datetime) +{ + int is_bcd, is_12hour; + grub_uint8_t value, flag; + + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + + is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); + + value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR); + if (is_bcd) + value = grub_bcd_to_num (value); + + datetime->year = value; + datetime->year += (value < 80) ? 2000 : 1900; + + value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH); + if (is_bcd) + value = grub_bcd_to_num (value); + + datetime->month = value; + + value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH); + if (is_bcd) + value = grub_bcd_to_num (value); + + datetime->day = value; + + is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR); + + value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR); + if (is_12hour) + { + is_12hour = (value & 0x80); + + value &= 0x7F; + value--; + } + + if (is_bcd) + value = grub_bcd_to_num (value); + + if (is_12hour) + value += 12; + + datetime->hour = value; + + value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE); + if (is_bcd) + value = grub_bcd_to_num (value); + + datetime->minute = value; + + value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND); + if (is_bcd) + value = grub_bcd_to_num (value); + + datetime->second = value; + + return 0; +} + +grub_err_t +grub_set_datetime (struct grub_datetime *datetime) +{ + int is_bcd, is_12hour; + grub_uint8_t value, flag; + + flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B); + + is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY); + + value = ((datetime->year >= 2000) ? datetime->year - 2000 : + datetime->year - 1900); + + if (is_bcd) + value = grub_num_to_bcd (value); + + grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value); + + value = datetime->month; + + if (is_bcd) + value = grub_num_to_bcd (value); + + grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value); + + value = datetime->day; + + if (is_bcd) + value = grub_num_to_bcd (value); + + grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value); + + value = datetime->hour; + + is_12hour = (! (flag & GRUB_CMOS_STATUS_B_24HOUR)); + + if (is_12hour) + { + value++; + + if (value > 12) + value -= 12; + else + is_12hour = 0; + } + + if (is_bcd) + value = grub_num_to_bcd (value); + + if (is_12hour) + value |= 0x80; + + grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value); + + value = datetime->minute; + + if (is_bcd) + value = grub_num_to_bcd (value); + + grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value); + + value = datetime->second; + + if (is_bcd) + value = grub_num_to_bcd (value); + + grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value); + + return 0; +} diff --git a/loader/aout.c b/loader/aout.c new file mode 100644 index 0000000..58b3992 --- /dev/null +++ b/loader/aout.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * 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, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +int +grub_aout_get_type (union grub_aout_header *header) +{ + int magic; + + magic = AOUT_GETMAGIC (header->aout32); + if ((magic == AOUT32_OMAGIC) || (magic == AOUT32_NMAGIC) || + (magic == AOUT32_ZMAGIC) || (magic == AOUT32_QMAGIC)) + return AOUT_TYPE_AOUT32; + else if ((magic == AOUT64_OMAGIC) || (magic == AOUT64_NMAGIC) || + (magic == AOUT64_ZMAGIC)) + return AOUT_TYPE_AOUT64; + else + return AOUT_TYPE_NONE; +} + +grub_err_t +grub_aout_load (grub_file_t file, int offset, + grub_addr_t load_addr, + int load_size, + grub_addr_t bss_end_addr) +{ + if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) + return grub_errno; + + if (!load_size) + load_size = file->size - offset; + + grub_file_read (file, (char *) load_addr, load_size); + + if (grub_errno) + return grub_errno; + + if (bss_end_addr) + grub_memset ((char *) load_addr + load_size, 0, + bss_end_addr - load_addr - load_size); + + return GRUB_ERR_NONE; +} diff --git a/loader/efi/appleloader.c b/loader/efi/appleloader.c new file mode 100644 index 0000000..910a13d --- /dev/null +++ b/loader/efi/appleloader.c @@ -0,0 +1,208 @@ +/* appleloader.c - apple legacy boot loader. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; + +static grub_efi_handle_t image_handle; +static grub_efi_char16_t *cmdline; + +static grub_err_t +grub_appleloader_unload (void) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_1 (b->unload_image, image_handle); + + grub_free (cmdline); + cmdline = 0; + + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_appleloader_boot (void) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_3 (b->start_image, image_handle, 0, 0); + + grub_appleloader_unload (); + + return grub_errno; +} + +/* early 2006 Core Duo / Core Solo models */ +static grub_uint8_t devpath_1[] = +{ + 0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF9, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B, + 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00, +}; + +/* mid-2006 Mac Pro (and probably other Core 2 models) */ +static grub_uint8_t devpath_2[] = +{ + 0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B, + 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00, +}; + +/* mid-2007 MBP ("Santa Rosa" based models) */ +static grub_uint8_t devpath_3[] = +{ + 0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B, + 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00, +}; + +/* early-2008 MBA */ +static grub_uint8_t devpath_4[] = +{ + 0x01, 0x03, 0x18, 0x00, 0x0B, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x06, 0x14, 0x00, 0xEB, 0x85, 0x05, 0x2B, + 0xB8, 0xD8, 0xA9, 0x49, 0x8B, 0x8C, 0xE2, 0x1B, + 0x01, 0xAE, 0xF2, 0xB7, 0x7F, 0xFF, 0x04, 0x00, +}; + +struct devdata +{ + char *model; + grub_efi_device_path_t *devpath; +}; + +struct devdata devs[] = +{ + {"Core Duo/Solo", (grub_efi_device_path_t *) devpath_1}, + {"Mac Pro", (grub_efi_device_path_t *) devpath_2}, + {"MBP", (grub_efi_device_path_t *) devpath_3}, + {"MBA", (grub_efi_device_path_t *) devpath_4}, + {NULL, NULL}, +}; + +static grub_err_t +grub_cmd_appleloader (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_efi_boot_services_t *b; + grub_efi_loaded_image_t *loaded_image; + struct devdata *pdev; + + grub_dl_ref (my_mod); + + /* Initialize some global variables. */ + image_handle = 0; + + b = grub_efi_system_table->boot_services; + + for (pdev = devs ; pdev->devpath ; pdev++) + if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath, + NULL, 0, &image_handle) == GRUB_EFI_SUCCESS) + break; + + if (! pdev->devpath) + { + grub_error (GRUB_ERR_BAD_OS, "can't find model"); + goto fail; + } + + grub_printf ("Model : %s\n", pdev->model); + + loaded_image = grub_efi_get_loaded_image (image_handle); + if (! loaded_image) + { + grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); + goto fail; + } + + if (argc > 0) + { + int i, len; + grub_efi_char16_t *p16; + + for (i = 0, len = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + len *= sizeof (grub_efi_char16_t); + cmdline = p16 = grub_malloc (len); + if (! cmdline) + goto fail; + + for (i = 0; i < argc; i++) + { + char *p8; + + p8 = argv[i]; + while (*p8) + *(p16++) = *(p8++); + + *(p16++) = ' '; + } + *(--p16) = 0; + + loaded_image->load_options = cmdline; + loaded_image->load_options_size = len; + } + + grub_loader_set (grub_appleloader_boot, grub_appleloader_unload, 0); + + return 0; + + fail: + + grub_dl_unref (my_mod); + return grub_errno; +} + +GRUB_MOD_INIT(appleloader) +{ + grub_register_command ("appleloader", grub_cmd_appleloader, + GRUB_COMMAND_FLAG_BOTH, + "appleloader [OPTS]", + "Boot legacy system.", 0); + + my_mod = mod; +} + +GRUB_MOD_FINI(appleloader) +{ + grub_unregister_command ("appleloader"); +} diff --git a/loader/efi/chainloader.c b/loader/efi/chainloader.c new file mode 100644 index 0000000..1ca5f1d --- /dev/null +++ b/loader/efi/chainloader.c @@ -0,0 +1,347 @@ +/* chainloader.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* TODO: support load options. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; + +static grub_efi_physical_address_t address; +static grub_efi_uintn_t pages; +static grub_efi_device_path_t *file_path; +static grub_efi_handle_t image_handle; +static grub_efi_char16_t *cmdline; + +static grub_err_t +grub_chainloader_unload (void) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_1 (b->unload_image, image_handle); + efi_call_2 (b->free_pages, address, pages); + + grub_free (file_path); + grub_free (cmdline); + cmdline = 0; + + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_chainloader_boot (void) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_uintn_t exit_data_size; + grub_efi_char16_t *exit_data; + + b = grub_efi_system_table->boot_services; + status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); + if (status != GRUB_EFI_SUCCESS) + { + if (exit_data) + { + char *buf; + + buf = grub_malloc (exit_data_size * 4 + 1); + if (buf) + { + *grub_utf16_to_utf8 ((grub_uint8_t *) buf, + exit_data, exit_data_size) = 0; + + grub_error (GRUB_ERR_BAD_OS, buf); + grub_free (buf); + } + else + grub_error (GRUB_ERR_BAD_OS, "unknown error"); + } + } + + if (exit_data) + efi_call_1 (b->free_pool, exit_data); + + grub_chainloader_unload (); + + return grub_errno; +} + +static void +copy_file_path (grub_efi_file_path_device_path_t *fp, + const char *str, grub_efi_uint16_t len) +{ + grub_efi_char16_t *p; + grub_efi_uint16_t size; + + fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; + fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; + size = len * sizeof (grub_efi_char16_t) + sizeof (*fp); + fp->header.length[0] = (grub_efi_uint8_t) (size & 0xff); + fp->header.length[1] = (grub_efi_uint8_t) (size >> 8); + for (p = fp->path_name; len > 0; len--, p++, str++) + { + /* FIXME: this assumes that the path is in ASCII. */ + *p = (grub_efi_char16_t) (*str == '/' ? '\\' : *str); + } +} + +static grub_efi_device_path_t * +make_file_path (grub_efi_device_path_t *dp, const char *filename) +{ + char *dir_start; + char *dir_end; + grub_size_t size; + grub_efi_device_path_t *d; + + dir_start = grub_strchr (filename, ')'); + if (! dir_start) + dir_start = (char *) filename; + else + dir_start++; + + dir_end = grub_strrchr (dir_start, '/'); + if (! dir_end) + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path"); + return 0; + } + + size = 0; + d = dp; + while (1) + { + size += GRUB_EFI_DEVICE_PATH_LENGTH (d); + if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d))) + break; + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + } + + file_path = grub_malloc (size + + ((grub_strlen (dir_start) + 1) + * sizeof (grub_efi_char16_t)) + + sizeof (grub_efi_file_path_device_path_t) * 2); + if (! file_path) + return 0; + + grub_memcpy (file_path, dp, size); + + /* Fill the file path for the directory. */ + d = (grub_efi_device_path_t *) ((char *) file_path + + ((char *) d - (char *) dp)); + grub_efi_print_device_path (d); + copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_start, dir_end - dir_start); + + /* Fill the file path for the file. */ + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_end + 1, grub_strlen (dir_end + 1)); + + /* Fill the end of device path nodes. */ + d = GRUB_EFI_NEXT_DEVICE_PATH (d); + d->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + d->length[0] = sizeof (*d); + d->length[1] = 0; + + return file_path; +} + +void +grub_rescue_cmd_chainloader (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_handle_t dev_handle = 0; + grub_device_t dev = 0; + grub_efi_device_path_t *dp = 0; + grub_efi_loaded_image_t *loaded_image; + char *filename; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + return; + } + filename = argv[0]; + + grub_dl_ref (my_mod); + + /* Initialize some global variables. */ + address = 0; + image_handle = 0; + file_path = 0; + + b = grub_efi_system_table->boot_services; + + file = grub_file_open (filename); + if (! file) + goto fail; + + /* Get the root device's device path. */ + dev = grub_device_open (0); + if (! dev) + goto fail; + + if (dev->disk) + { + dev_handle = grub_efidisk_get_device_handle (dev->disk); + if (dev_handle) + dp = grub_efi_get_device_path (dev_handle); + } + + if (! dev->disk || ! dev_handle || ! dp) + { + grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device"); + goto fail; + } + + file_path = make_file_path (dp, filename); + if (! file_path) + goto fail; + + grub_printf ("file path: "); + grub_efi_print_device_path (file_path); + + size = grub_file_size (file); + pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); + + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_LOADER_CODE, + pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate %u pages", pages); + goto fail; + } + + if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_OS, "too small"); + + goto fail; + } + + status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, + (void *) ((grub_addr_t) address), size, + &image_handle); + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); + else + grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + + goto fail; + } + + /* LoadImage does not set a device handler when the image is + loaded from memory, so it is necessary to set it explicitly here. + This is a mess. */ + loaded_image = grub_efi_get_loaded_image (image_handle); + if (! loaded_image) + { + grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); + goto fail; + } + loaded_image->device_handle = dev_handle; + + grub_file_close (file); + + if (argc > 1) + { + int i, len; + grub_efi_char16_t *p16; + + for (i = 1, len = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + len *= sizeof (grub_efi_char16_t); + cmdline = p16 = grub_malloc (len); + if (! cmdline) + goto fail; + + for (i = 1; i < argc; i++) + { + char *p8; + + p8 = argv[i]; + while (*p8) + *(p16++) = *(p8++); + + *(p16++) = ' '; + } + *(--p16) = 0; + + loaded_image->load_options = cmdline; + loaded_image->load_options_size = len; + } + + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); + return; + + fail: + + if (dev) + grub_device_close (dev); + + if (file) + grub_file_close (file); + + if (file_path) + grub_free (file_path); + + if (address) + efi_call_2 (b->free_pages, address, pages); + + grub_dl_unref (my_mod); +} + +static const char loader_name[] = "chainloader"; + +GRUB_MOD_INIT(chainloader) +{ + grub_rescue_register_command (loader_name, + grub_rescue_cmd_chainloader, + "load another boot loader"); + my_mod = mod; +} + +GRUB_MOD_FINI(chainloader) +{ + grub_rescue_unregister_command (loader_name); +} diff --git a/loader/efi/chainloader_normal.c b/loader/efi/chainloader_normal.c new file mode 100644 index 0000000..455669e --- /dev/null +++ b/loader/efi/chainloader_normal.c @@ -0,0 +1,48 @@ +/* chainloader_normal.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +chainloader_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + if (argc == 0) + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + else + grub_rescue_cmd_chainloader (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(chainloader_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("chainloader", chainloader_command, + GRUB_COMMAND_FLAG_BOTH, + "chainloader FILE", + "Prepare to boot another boot loader.", 0); +} + +GRUB_MOD_FINI(chainloader_normal) +{ + grub_unregister_command ("chainloader"); +} diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c new file mode 100644 index 0000000..25d0f59 --- /dev/null +++ b/loader/i386/bsd.c @@ -0,0 +1,773 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ALIGN_DWORD(a) ALIGN_UP (a, 4) +#define ALIGN_PAGE(a) ALIGN_UP (a, 4096) + +#define MOD_BUF_ALLOC_UNIT 4096 + +static int kernel_type; +static grub_dl_t my_mod; +static grub_addr_t entry, kern_start, kern_end; +static grub_uint32_t bootflags; +static char *mod_buf; +static grub_uint32_t mod_buf_len, mod_buf_max; +static int is_elf_kernel; + +static const char freebsd_opts[] = "DhaCcdgmnpqrsv"; +static const grub_uint32_t freebsd_flags[] = +{ + FREEBSD_RB_DUAL, FREEBSD_RB_SERIAL, FREEBSD_RB_ASKNAME, + FREEBSD_RB_CDROM, FREEBSD_RB_CONFIG, FREEBSD_RB_KDB, + FREEBSD_RB_GDB, FREEBSD_RB_MUTE, FREEBSD_RB_NOINTR, + FREEBSD_RB_PAUSE, FREEBSD_RB_QUIET, FREEBSD_RB_DFLTROOT, + FREEBSD_RB_SINGLE, FREEBSD_RB_VERBOSE +}; + +static const char openbsd_opts[] = "abcsd"; +static const grub_uint32_t openbsd_flags[] = +{ + OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG, + OPENBSD_RB_SINGLE, OPENBSD_RB_KDB +}; + +static const char netbsd_opts[] = "abcdmqsvxz"; +static const grub_uint32_t netbsd_flags[] = +{ + NETBSD_RB_ASKNAME, NETBSD_RB_HALT, NETBSD_RB_USERCONFIG, + NETBSD_RB_KDB, NETBSD_RB_MINIROOT, NETBSD_AB_QUIET, + NETBSD_RB_SINGLE, NETBSD_AB_VERBOSE, NETBSD_AB_DEBUG, + NETBSD_AB_SILENT +}; + +static void +grub_bsd_get_device (grub_uint32_t * biosdev, + grub_uint32_t * unit, + grub_uint32_t * slice, grub_uint32_t * part) +{ + char *p; + + *biosdev = *unit = *slice = *part = 0; + p = grub_env_get ("root"); + if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') && + (p[2] >= '0') && (p[2] <= '9')) + { + if (p[0] == 'h') + *biosdev = 0x80; + + *unit = grub_strtoul (p + 2, &p, 0); + *biosdev += *unit; + + if ((p) && (p[0] == ',')) + { + if ((p[1] >= '0') && (p[1] <= '9')) + { + *slice = grub_strtoul (p + 1, &p, 0); + + if ((p) && (p[0] == ',')) + p++; + } + + if ((p[0] >= 'a') && (p[0] <= 'z')) + *part = p[0] - 'a'; + } + } +} + +static grub_err_t +grub_freebsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len) +{ + if (mod_buf_max < mod_buf_len + len + 8) + { + char *new_buf; + + do + { + mod_buf_max += MOD_BUF_ALLOC_UNIT; + } + while (mod_buf_max < mod_buf_len + len + 8); + + new_buf = grub_malloc (mod_buf_max); + if (!new_buf) + return grub_errno; + + grub_memcpy (new_buf, mod_buf, mod_buf_len); + grub_free (mod_buf); + + mod_buf = new_buf; + } + + *((grub_uint32_t *) (mod_buf + mod_buf_len)) = type; + *((grub_uint32_t *) (mod_buf + mod_buf_len + 4)) = len; + mod_buf_len += 8; + + if (len) + grub_memcpy (mod_buf + mod_buf_len, data, len); + + mod_buf_len = ALIGN_DWORD (mod_buf_len + len); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_freebsd_add_meta_module (int is_kern, int argc, char **argv, + grub_addr_t addr, grub_uint32_t size) +{ + char *name, *type; + + name = grub_strrchr (argv[0], '/'); + if (name) + name++; + else + name = argv[0]; + + if (grub_freebsd_add_meta (FREEBSD_MODINFO_NAME, name, + grub_strlen (name) + 1)) + return grub_errno; + + argc--; + argv++; + + if ((argc) && (!grub_memcmp (argv[0], "type=", 5))) + { + type = &argv[0][5]; + argc--; + argv++; + } + else + type = (is_kern) ? FREEBSD_MODTYPE_KERNEL : FREEBSD_MODTYPE_RAW; + + if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type, + grub_strlen (type) + 1)) || + (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr, sizeof (addr))) || + (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size, sizeof (size)))) + return grub_errno; + + if (argc) + { + int i, n; + + n = 0; + for (i = 0; i < argc; i++) + { + n += grub_strlen (argv[i]) + 1; + } + + if (n) + { + char cmdline[n], *p; + + p = cmdline; + for (i = 0; i < argc; i++) + { + grub_strcpy (p, argv[i]); + p += grub_strlen (argv[i]); + *(p++) = ' '; + } + *p = 0; + + if (grub_freebsd_add_meta (FREEBSD_MODINFO_ARGS, cmdline, n)) + return grub_errno; + } + } + + return GRUB_ERR_NONE; +} + +static void +grub_freebsd_list_modules (void) +{ + grub_uint32_t pos = 0; + + grub_printf (" %-18s %-18s%14s%14s\n", "name", "type", "addr", "size"); + while (pos < mod_buf_len) + { + grub_uint32_t type, size; + + type = *((grub_uint32_t *) (mod_buf + pos)); + size = *((grub_uint32_t *) (mod_buf + pos + 4)); + pos += 8; + switch (type) + { + case FREEBSD_MODINFO_NAME: + case FREEBSD_MODINFO_TYPE: + grub_printf (" %-18s", mod_buf + pos); + break; + case FREEBSD_MODINFO_ADDR: + { + grub_addr_t addr; + + addr = *((grub_addr_t *) (mod_buf + pos)); + grub_printf (" 0x%08x", addr); + break; + } + case FREEBSD_MODINFO_SIZE: + { + grub_uint32_t len; + + len = *((grub_uint32_t *) (mod_buf + pos)); + grub_printf (" 0x%08x\n", len); + } + } + + pos = ALIGN_DWORD (pos + size); + } +} + +static grub_err_t +grub_freebsd_boot (void) +{ + struct grub_freebsd_bootinfo bi; + char *p; + grub_uint32_t bootdev, biosdev, unit, slice, part; + + auto int iterate_env (struct grub_env_var *var); + int iterate_env (struct grub_env_var *var) + { + if ((!grub_memcmp (var->name, "FreeBSD.", 8)) && (var->name[8])) + { + grub_strcpy (p, &var->name[8]); + p += grub_strlen (p); + *(p++) = '='; + grub_strcpy (p, var->value); + p += grub_strlen (p) + 1; + } + + return 0; + } + + grub_memset (&bi, 0, sizeof (bi)); + bi.bi_version = FREEBSD_BOOTINFO_VERSION; + bi.bi_size = sizeof (bi); + + grub_bsd_get_device (&biosdev, &unit, &slice, &part); + bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + + (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); + + bi.bi_bios_dev = biosdev; + + p = (char *) kern_end; + + grub_env_iterate (iterate_env); + + if (p != (char *) kern_end) + { + *(p++) = 0; + + bi.bi_envp = kern_end; + kern_end = ALIGN_PAGE ((grub_uint32_t) p); + } + + if (is_elf_kernel) + { + if (grub_freebsd_add_meta (FREEBSD_MODINFO_END, 0, 0)) + return grub_errno; + + grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len); + bi.bi_modulep = kern_end; + + kern_end = ALIGN_PAGE (kern_end + mod_buf_len); + } + + bi.bi_kernend = kern_end; + + grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev, + 0, 0, 0, &bi, bi.bi_modulep, kern_end); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_openbsd_boot (void) +{ + char *buf = (char *) GRUB_BSD_TEMP_BUFFER; + struct grub_machine_mmap_entry mmap; + struct grub_openbsd_bios_mmap *pm; + struct grub_openbsd_bootargs *pa; + grub_uint32_t bootdev, biosdev, unit, slice, part, cont; + + pa = (struct grub_openbsd_bootargs *) buf; + + pa->ba_type = OPENBSD_BOOTARG_MMAP; + pm = (struct grub_openbsd_bios_mmap *) (pa + 1); + cont = grub_get_mmap_entry (&mmap, 0); + if (mmap.size) + do + { + pm->addr = mmap.addr; + pm->len = mmap.len; + pm->type = mmap.type; + pm++; + + if (!cont) + break; + + cont = grub_get_mmap_entry (&mmap, cont); + } + while (mmap.size); + + pa->ba_size = (char *) pm - (char *) pa; + pa->ba_next = (struct grub_openbsd_bootargs *) pm; + pa = pa->ba_next; + pa->ba_type = OPENBSD_BOOTARG_END; + pa++; + + grub_bsd_get_device (&biosdev, &unit, &slice, &part); + bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) + + (part << OPENBSD_B_PARTSHIFT)); + + grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER, + 0, grub_upper_mem >> 10, grub_lower_mem >> 10, + (char *) pa - buf, buf); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_netbsd_boot (void) +{ + struct grub_netbsd_btinfo_rootdevice *rootdev; + struct grub_netbsd_bootinfo *bootinfo; + grub_uint32_t biosdev, unit, slice, part; + + grub_bsd_get_device (&biosdev, &unit, &slice, &part); + + rootdev = (struct grub_netbsd_btinfo_rootdevice *) GRUB_BSD_TEMP_BUFFER; + + rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice); + rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE; + grub_sprintf (rootdev->devname, "%cd%d%c", (biosdev & 0x80) ? 'w' : 'f', + unit, 'a' + part); + + bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1); + bootinfo->bi_count = 1; + bootinfo->bi_data[0] = rootdev; + + grub_unix_real_boot (entry, bootflags, 0, bootinfo, + 0, grub_upper_mem >> 10, grub_lower_mem >> 10); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bsd_unload (void) +{ + if (mod_buf) + { + grub_free (mod_buf); + mod_buf = 0; + mod_buf_max = 0; + } + + kernel_type = KERNEL_TYPE_NONE; + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bsd_load_aout (grub_file_t file) +{ + grub_addr_t load_addr, bss_end_addr; + int ofs, align_page; + union grub_aout_header ah; + + if ((grub_file_seek (file, 0)) == (grub_off_t) - 1) + return grub_errno; + + if (grub_file_read (file, (char *) &ah, sizeof (ah)) != sizeof (ah)) + return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header"); + + if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32) + return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header"); + + entry = ah.aout32.a_entry & 0xFFFFFF; + + if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC) + { + load_addr = entry; + ofs = 0x1000; + align_page = 0; + } + else + { + load_addr = entry & 0xF00000; + ofs = sizeof (struct grub_aout32_header); + align_page = 1; + } + + if (load_addr < 0x100000) + return grub_error (GRUB_ERR_BAD_OS, "load address below 1M"); + + kern_start = load_addr; + kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data; + if (align_page) + kern_end = ALIGN_PAGE (kern_end); + + if (ah.aout32.a_bss) + { + kern_end += ah.aout32.a_bss; + if (align_page) + kern_end = ALIGN_PAGE (kern_end); + + bss_end_addr = kern_end; + } + else + bss_end_addr = 0; + + return grub_aout_load (file, ofs, load_addr, + ah.aout32.a_text + ah.aout32.a_data, bss_end_addr); +} + +static grub_err_t +grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr) +{ + Elf32_Addr paddr; + + phdr->p_paddr &= 0xFFFFFF; + paddr = phdr->p_paddr; + + if ((paddr < grub_os_area_addr) + || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", + paddr); + + if ((!kern_start) || (paddr < kern_start)) + kern_start = paddr; + + if (paddr + phdr->p_memsz > kern_end) + kern_end = paddr + phdr->p_memsz; + + *addr = paddr; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_bsd_load_elf (grub_elf_t elf) +{ + kern_start = kern_end = 0; + + if (grub_elf_is_elf32 (elf)) + { + entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; + return grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0); + } + else + return grub_error (GRUB_ERR_BAD_OS, "invalid elf"); +} + +static grub_err_t +grub_bsd_load (int argc, char *argv[]) +{ + grub_file_t file; + grub_elf_t elf; + + grub_dl_ref (my_mod); + + grub_loader_unset (); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (!file) + goto fail; + + elf = grub_elf_file (file); + if (elf) + { + is_elf_kernel = 1; + grub_bsd_load_elf (elf); + grub_elf_close (elf); + } + else + { + is_elf_kernel = 0; + grub_errno = 0; + grub_bsd_load_aout (file); + grub_file_close (file); + } + +fail: + + if (grub_errno != GRUB_ERR_NONE) + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_uint32_t +grub_bsd_parse_flags (char *str, const char *opts, + const grub_uint32_t * flags) +{ + grub_uint32_t result = 0; + + while (*str) + { + const char *po; + const grub_uint32_t *pf; + + po = opts; + pf = flags; + while (*po) + { + if (*str == *po) + { + result |= *pf; + break; + } + po++; + pf++; + } + str++; + } + + return result; +} + +void +grub_rescue_cmd_freebsd (int argc, char *argv[]) +{ + kernel_type = KERNEL_TYPE_FREEBSD; + bootflags = ((argc <= 1) ? 0 : + grub_bsd_parse_flags (argv[1], freebsd_opts, freebsd_flags)); + + if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) + { + kern_end = ALIGN_PAGE (kern_end); + if ((is_elf_kernel) && + (grub_freebsd_add_meta_module (1, argc, argv, kern_start, + kern_end - kern_start))) + return; + grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1); + } +} + +void +grub_rescue_cmd_openbsd (int argc, char *argv[]) +{ + kernel_type = KERNEL_TYPE_OPENBSD; + bootflags = ((argc <= 1) ? 0 : + grub_bsd_parse_flags (argv[1], openbsd_opts, openbsd_flags)); + + if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) + grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1); +} + +void +grub_rescue_cmd_netbsd (int argc, char *argv[]) +{ + kernel_type = KERNEL_TYPE_NETBSD; + bootflags = ((argc <= 1) ? 0 : + grub_bsd_parse_flags (argv[1], netbsd_opts, netbsd_flags)); + + if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) + grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1); +} + +void +grub_rescue_cmd_freebsd_loadenv (int argc, char *argv[]) +{ + grub_file_t file = 0; + char *buf = 0, *curr, *next; + int len; + + if (kernel_type != KERNEL_TYPE_FREEBSD) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "only freebsd support environment"); + return; + } + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no filename"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if ((!file) || (!file->size)) + goto fail; + + len = file->size; + buf = grub_malloc (len + 1); + if (!buf) + goto fail; + + if (grub_file_read (file, buf, len) != len) + goto fail; + + buf[len] = 0; + + next = buf; + while (next) + { + char *p; + + curr = next; + next = grub_strchr (curr, '\n'); + if (next) + { + + p = next - 1; + while (p > curr) + { + if ((*p != '\r') && (*p != ' ') && (*p != '\t')) + break; + p--; + } + + if ((p > curr) && (*p == '"')) + p--; + + *(p + 1) = 0; + next++; + } + + if (*curr == '#') + continue; + + p = grub_strchr (curr, '='); + if (!p) + continue; + + *(p++) = 0; + + if (*curr) + { + char name[grub_strlen (curr) + 8 + 1]; + + if (*p == '"') + p++; + + grub_sprintf (name, "FreeBSD.%s", curr); + if (grub_env_set (name, p)) + goto fail; + } + } + +fail: + grub_free (buf); + + if (file) + grub_file_close (file); +} + +void +grub_rescue_cmd_freebsd_module (int argc, char *argv[]) +{ + grub_file_t file = 0; + + if (kernel_type != KERNEL_TYPE_FREEBSD) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "only freebsd support module"); + return; + } + + if (!is_elf_kernel) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "only elf kernel support module"); + return; + } + + /* List the current modules if no parameter. */ + if (!argc) + { + grub_freebsd_list_modules (); + return; + } + + file = grub_gzfile_open (argv[0], 1); + if ((!file) || (!file->size)) + goto fail; + + if (kern_end + file->size > grub_os_area_addr + grub_os_area_size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module"); + goto fail; + } + + grub_file_read (file, (char *) kern_end, file->size); + if ((!grub_errno) && + (!grub_freebsd_add_meta_module (0, argc, argv, kern_end, file->size))) + kern_end = ALIGN_PAGE (kern_end + file->size); + +fail: + if (file) + grub_file_close (file); +} + +GRUB_MOD_INIT (bsd) +{ + grub_rescue_register_command ("freebsd", + grub_rescue_cmd_freebsd, + "load freebsd kernel"); + grub_rescue_register_command ("openbsd", + grub_rescue_cmd_openbsd, + "load openbsd kernel"); + grub_rescue_register_command ("netbsd", + grub_rescue_cmd_netbsd, "load netbsd kernel"); + + grub_rescue_register_command ("freebsd_loadenv", + grub_rescue_cmd_freebsd_loadenv, + "load freebsd env"); + grub_rescue_register_command ("freebsd_module", + grub_rescue_cmd_freebsd_module, + "load freebsd module"); + + my_mod = mod; +} + +GRUB_MOD_FINI (bsd) +{ + grub_rescue_unregister_command ("freebsd"); + grub_rescue_unregister_command ("openbsd"); + grub_rescue_unregister_command ("netbsd"); + + grub_rescue_unregister_command ("freebsd_loadenv"); + grub_rescue_unregister_command ("freebsd_module"); + + if (mod_buf) + { + grub_free (mod_buf); + mod_buf = 0; + mod_buf_max = 0; + } +} diff --git a/loader/i386/bsd_normal.c b/loader/i386/bsd_normal.c new file mode 100644 index 0000000..73b39a6 --- /dev/null +++ b/loader/i386/bsd_normal.c @@ -0,0 +1,102 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_normal_freebsd_command (struct grub_arg_list *state + __attribute__ ((unused)), int argc, char **args) +{ + grub_rescue_cmd_freebsd (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_openbsd_command (struct grub_arg_list *state + __attribute__ ((unused)), int argc, char **args) +{ + grub_rescue_cmd_openbsd (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_netbsd_command (struct grub_arg_list *state + __attribute__ ((unused)), int argc, char **args) +{ + grub_rescue_cmd_netbsd (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_freebsd_loadenv_command (struct grub_arg_list *state + __attribute__ ((unused)), int argc, + char **args) +{ + grub_rescue_cmd_freebsd_loadenv (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_freebsd_module_command (struct grub_arg_list *state + __attribute__ ((unused)), int argc, + char **args) +{ + grub_rescue_cmd_freebsd_module (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT (bsd_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("freebsd", grub_normal_freebsd_command, + GRUB_COMMAND_FLAG_BOTH, + "freebsd FILE [OPTS] [ARGS...]", + "Load freebsd kernel.", 0); + grub_register_command ("openbsd", grub_normal_openbsd_command, + GRUB_COMMAND_FLAG_BOTH, + "openbsd FILE [OPTS]", "Load openbsd kernel.", 0); + grub_register_command ("netbsd", grub_normal_netbsd_command, + GRUB_COMMAND_FLAG_BOTH, + "netbsd FILE [OPTS]", "Load netbsd kernel.", 0); + + grub_register_command ("freebsd_loadenv", + grub_normal_freebsd_loadenv_command, + GRUB_COMMAND_FLAG_BOTH, + "freebsd_loadenv FILE", "Load freebsd env.", 0); + grub_register_command ("freebsd_module", + grub_normal_freebsd_module_command, + GRUB_COMMAND_FLAG_BOTH, + "freebsd_module [FILE [type=module_type] [ARGS...]]", + "Load freebsd module.", 0); +} + +GRUB_MOD_FINI (bsd_normal) +{ + grub_unregister_command ("freebsd"); + grub_unregister_command ("openbsd"); + grub_unregister_command ("netbsd"); + + grub_unregister_command ("freebsd_loadenv"); + grub_unregister_command ("freebsd_module"); +} diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c new file mode 100644 index 0000000..50e1ff1 --- /dev/null +++ b/loader/i386/efi/linux.c @@ -0,0 +1,972 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_LINUX_CL_OFFSET 0x1000 +#define GRUB_LINUX_CL_END_OFFSET 0x2000 + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +static grub_dl_t my_mod; + +static grub_size_t linux_mem_size; +static int loaded; +static void *real_mode_mem; +static void *prot_mode_mem; +static void *initrd_mem; +static grub_efi_uintn_t real_mode_pages; +static grub_efi_uintn_t prot_mode_pages; +static grub_efi_uintn_t initrd_pages; +static void *mmap_buf; + +static grub_uint8_t gdt[] __attribute__ ((aligned(16))) = + { + /* NULL. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Reserved. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Code segment. */ + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00, + /* Data segment. */ + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + }; + +struct gdt_descriptor +{ + grub_uint16_t limit; + void *base; +} __attribute__ ((packed)); + +static struct gdt_descriptor gdt_desc = + { + sizeof (gdt) - 1, + gdt + }; + +struct idt_descriptor +{ + grub_uint16_t limit; + void *base; +} __attribute__ ((packed)); + +static struct idt_descriptor idt_desc = + { + 0, + 0 + }; + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Find the optimal number of pages for the memory map. Is it better to + move this code to efi/mm.c? */ +static grub_efi_uintn_t +find_mmap_size (void) +{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0) + return mmap_size; + + mmap_size = (1 << 12); + while (1) + { + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; + + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); + grub_free (mmap); + + if (ret < 0) + grub_fatal ("cannot get memory map"); + else if (ret > 0) + break; + + mmap_size += (1 << 12); + } + + /* Increase the size a bit for safety, because GRUB allocates more on + later, and EFI itself may allocate more. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + +static void +free_pages (void) +{ + if (real_mode_mem) + { + grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages); + real_mode_mem = 0; + } + + if (prot_mode_mem) + { + grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages); + prot_mode_mem = 0; + } + + if (initrd_mem) + { + grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + initrd_mem = 0; + } +} + +/* Allocate pages for the real mode code and the protected mode code + for linux as well as a memory map buffer. */ +static int +allocate_pages (grub_size_t prot_size) +{ + grub_efi_uintn_t desc_size; + grub_efi_memory_descriptor_t *mmap, *mmap_end; + grub_efi_uintn_t mmap_size, tmp_mmap_size; + grub_efi_memory_descriptor_t *desc; + grub_size_t real_size; + + /* Make sure that each size is aligned to a page boundary. */ + real_size = GRUB_LINUX_CL_END_OFFSET; + prot_size = page_align (prot_size); + mmap_size = find_mmap_size (); + + grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n", + (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size); + + /* Calculate the number of pages; Combine the real mode code with + the memory map buffer for simplicity. */ + real_mode_pages = ((real_size + mmap_size) >> 12); + prot_mode_pages = (prot_size >> 12); + + /* Initialize the memory pointers with NULL for convenience. */ + real_mode_mem = 0; + prot_mode_mem = 0; + + /* Read the memory map temporarily, to find free space. */ + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + tmp_mmap_size = mmap_size; + if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0) + grub_fatal ("cannot get memory map"); + + mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size); + + /* First, find free pages for the real mode code + and the memory map buffer. */ + for (desc = mmap; + desc < mmap_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + /* Probably it is better to put the real mode code in the traditional + space for safety. */ + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY + && desc->physical_start <= 0x90000 + && desc->num_pages >= real_mode_pages) + { + grub_efi_physical_address_t physical_end; + grub_efi_physical_address_t addr; + + physical_end = desc->physical_start + (desc->num_pages << 12); + if (physical_end > 0x90000) + physical_end = 0x90000; + + grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n", + (unsigned) desc->physical_start, + (unsigned) physical_end); + addr = physical_end - real_size - mmap_size; + if (addr < 0x10000) + continue; + + grub_dprintf ("linux", "trying to allocate %u pages at %lx\n", + (unsigned) real_mode_pages, (unsigned long) addr); + real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages); + if (! real_mode_mem) + grub_fatal ("cannot allocate pages"); + + desc->num_pages -= real_mode_pages; + break; + } + } + + if (! real_mode_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + goto fail; + } + + mmap_buf = (void *) ((char *) real_mode_mem + real_size); + + /* Next, find free pages for the protected mode code. */ + /* XXX what happens if anything is using this address? */ + prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages); + if (! prot_mode_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + "cannot allocate protected mode pages"); + goto fail; + } + + grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, " + "prot_mode_mem = %lx, prot_mode_pages = %x\n", + (unsigned long) real_mode_mem, (unsigned) real_mode_pages, + (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages); + + grub_free (mmap); + return 1; + + fail: + grub_free (mmap); + free_pages (); + return 0; +} + +static void +grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, + grub_uint64_t start, grub_uint64_t size, + grub_uint32_t type) +{ + int n = *e820_num; + + if (n >= GRUB_E820_MAX_ENTRY) + grub_fatal ("Too many e820 memory map entries"); + + if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && + (e820_map[n - 1].type == type)) + e820_map[n - 1].size += size; + else + { + e820_map[n].addr = start; + e820_map[n].size = size; + e820_map[n].type = type; + (*e820_num)++; + } +} + +#ifdef __x86_64__ +struct +{ + grub_uint32_t kernel_entry; + grub_uint32_t kernel_cs; +} jumpvector; +#endif + +static grub_err_t +grub_linux_boot (void) +{ + struct linux_kernel_params *params; + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t map_key; + grub_efi_uintn_t desc_size; + grub_efi_uint32_t desc_version; + grub_efi_memory_descriptor_t *desc; + int e820_num; + + params = real_mode_mem; + + grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n", + (unsigned) params->code32_start, + (unsigned long) &(idt_desc.limit), + (unsigned long) &(gdt_desc.limit)); + grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n", + (unsigned) idt_desc.limit, (unsigned long) idt_desc.base, + (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base); + + mmap_size = find_mmap_size (); + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key, + &desc_size, &desc_version) <= 0) + grub_fatal ("cannot get memory map"); + + e820_num = 0; + for (desc = mmap_buf; + desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + switch (desc->type) + { + case GRUB_EFI_ACPI_RECLAIM_MEMORY: + grub_e820_add_region (params->e820_map, &e820_num, + desc->physical_start, + desc->num_pages << 12, + GRUB_E820_ACPI); + break; + + case GRUB_EFI_ACPI_MEMORY_NVS: + grub_e820_add_region (params->e820_map, &e820_num, + desc->physical_start, + desc->num_pages << 12, + GRUB_E820_NVS); + break; + + case GRUB_EFI_RUNTIME_SERVICES_CODE: + grub_e820_add_region (params->e820_map, &e820_num, + desc->physical_start, + desc->num_pages << 12, + GRUB_E820_EXEC_CODE); + break; + + case GRUB_EFI_LOADER_CODE: + case GRUB_EFI_LOADER_DATA: + case GRUB_EFI_BOOT_SERVICES_CODE: + case GRUB_EFI_BOOT_SERVICES_DATA: + case GRUB_EFI_CONVENTIONAL_MEMORY: + { + grub_uint64_t start, size, end; + + start = desc->physical_start; + size = desc->num_pages << 12; + end = start + size; + + /* Skip A0000 - 100000 region. */ + if ((start < 0x100000ULL) && (end > 0xA0000ULL)) + { + if (start < 0xA0000ULL) + { + grub_e820_add_region (params->e820_map, &e820_num, + start, + 0xA0000ULL - start, + GRUB_E820_RAM); + } + + if (end <= 0x100000ULL) + continue; + + start = 0x100000ULL; + size = end - start; + } + + grub_e820_add_region (params->e820_map, &e820_num, + start, size, GRUB_E820_RAM); + break; + } + + default: + grub_e820_add_region (params->e820_map, &e820_num, + desc->physical_start, + desc->num_pages << 12, + GRUB_E820_RESERVED); + } + } + + params->mmap_size = e820_num; + + if (! grub_efi_exit_boot_services (map_key)) + grub_fatal ("cannot exit boot services"); + + /* Note that no boot services are available from here. */ + + /* Pass EFI parameters. */ + if (grub_le_to_cpu16 (params->version) >= 0x0206) + { + params->v0206.efi_mem_desc_size = desc_size; + params->v0206.efi_mem_desc_version = desc_version; + params->v0206.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf; + params->v0206.efi_mmap_size = mmap_size; +#ifdef __x86_64__ + params->v0206.efi_mmap_hi = (grub_uint32_t) ((grub_uint64_t) mmap_buf >> 32); +#endif + } + else if (grub_le_to_cpu16 (params->version) >= 0x0204) + { + params->v0204.efi_mem_desc_size = desc_size; + params->v0204.efi_mem_desc_version = desc_version; + params->v0204.efi_mmap = (grub_uint32_t) (unsigned long) mmap_buf; + params->v0204.efi_mmap_size = mmap_size; + } + + /* Hardware interrupts are not safe any longer. */ + asm volatile ("cli" : : ); + + /* Load the IDT and the GDT for the bootstrap. */ + asm volatile ("lidt %0" : : "m" (idt_desc)); + asm volatile ("lgdt %0" : : "m" (gdt_desc)); + +#ifdef __x86_64__ + + jumpvector.kernel_entry = (grub_uint64_t) grub_linux_real_boot; + jumpvector.kernel_cs = 0x10; + + asm volatile ( "mov %0, %%rbx" : : "m" (params->code32_start)); + asm volatile ( "mov %0, %%rsi" : : "m" (real_mode_mem)); + + asm volatile ( "ljmp *%0" : : "m" (jumpvector)); + +#else + + /* Pass parameters. */ + asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start)); + asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem)); + + asm volatile ("xorl %%ebx, %%ebx" : : ); + + /* Enter Linux. */ + asm volatile ("jmp *%%ecx" : : ); + +#endif + + /* Never reach here. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + free_pages (); + grub_dl_unref (my_mod); + loaded = 0; + return GRUB_ERR_NONE; +} + +grub_uint64_t video_base; + +static int +grub_find_video_card (int bus, int dev, int func, + grub_pci_id_t pciid __attribute__ ((unused))) +{ + grub_pci_address_t addr; + + addr = grub_pci_make_address (bus, dev, func, 2); + + if (grub_pci_read (addr) >> 24 == 0x3) + { + int i; + + addr = grub_pci_make_address (bus, dev, func, 4); + for (i = 0; i < 6; i++, addr += 4) + { + grub_uint32_t base, type; + + base = grub_pci_read (addr); + + if ((base == 0) || (base == 0xffffffff) || + (base & GRUB_PCI_ADDR_SPACE_IO)) + continue; + + type = base & GRUB_PCI_ADDR_MEM_TYPE_MASK; + if (! (addr & GRUB_PCI_ADDR_MEM_PREFETCH)) + { + if (type == GRUB_PCI_ADDR_MEM_TYPE_64) + { + i++; + addr +=4 ; + } + continue; + } + + base &= GRUB_PCI_ADDR_MEM_MASK; + if (type == GRUB_PCI_ADDR_MEM_TYPE_64) + { + if (i == 5) + break; + + video_base = grub_pci_read (addr + 4); + video_base <<= 32; + } + + video_base |= base; + + return 1; + } + } + + return 0; +} + +static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; + +static int +grub_linux_setup_video (struct linux_kernel_params *params) +{ + grub_efi_uga_draw_protocol_t *c; + grub_uint32_t width, height, depth, rate; + + c = grub_efi_locate_protocol (&uga_draw_guid, 0); + if (! c) + return 1; + + if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate)) + return 1; + + grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate); + + video_base = 0; + grub_pci_iterate (grub_find_video_card); + + if (! video_base) + { + grub_printf ("Can\'t find frame buffer address\n"); + return 1; + } + + grub_printf ("Video frame buffer: %llx\n", (unsigned long long) video_base); + + params->lfb_width = width; + params->lfb_height = height; + params->lfb_depth = depth; + + /* FIXME: shouldn't use fixed value. */ + params->lfb_line_len = 8192; + + params->lfb_base = video_base; + params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16; + + params->red_mask_size = 8; + params->red_field_pos = 16; + params->green_mask_size = 8; + params->green_field_pos = 8; + params->blue_mask_size = 8; + params->blue_field_pos = 0; + params->reserved_mask_size = 8; + params->reserved_field_pos = 24; + + return 0; +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_kernel_header lh; + struct linux_kernel_params *params; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size; + grub_ssize_t len; + int i; + char *dest; + int video_type; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + if (grub_file_read (file, (char *) &lh, sizeof (lh)) != sizeof (lh)) + { + grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header"); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, "too many setup sectors"); + goto fail; + } + + /* EFI support is quite new, so reject old versions. */ + if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) + || grub_le_to_cpu16 (lh.version) < 0x0203) + { + grub_error (GRUB_ERR_BAD_OS, "too old version"); + goto fail; + } + + /* I'm not sure how to support zImage on EFI. */ + if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) + { + grub_error (GRUB_ERR_BAD_OS, "zImage is not supported"); + goto fail; + } + + setup_sects = lh.setup_sects; + + /* If SETUP_SECTS is not set, set it to the default (4). */ + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + if (! allocate_pages (prot_size)) + goto fail; + + params = (struct linux_kernel_params *) real_mode_mem; + grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET); + grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); + + params->ps_mouse = params->padding10 = 0; + + len = 0x400 - sizeof (lh); + if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + /* XXX Linux assumes that only elilo can boot Linux on EFI!!! */ + params->type_of_loader = (LINUX_LOADER_ID_ELILO << 4); + + params->cl_magic = GRUB_LINUX_CL_MAGIC; + params->cl_offset = 0x1000; + params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000; + params->ramdisk_image = 0; + params->ramdisk_size = 0; + + params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; + params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + + /* These are not needed to be precise, because Linux uses these values + only to raise an error when the decompression code cannot find good + space. */ + params->ext_mem = ((32 * 0x100000) >> 10); + params->alt_mem = ((32 * 0x100000) >> 10); + + params->video_cursor_x = grub_getxy () >> 8; + params->video_cursor_y = grub_getxy () & 0xff; + params->video_page = 0; /* ??? */ + params->video_mode = grub_efi_system_table->con_out->mode->mode; + params->video_width = (grub_getwh () >> 8); + params->video_ega_bx = 0; + params->video_height = (grub_getwh () & 0xff); + params->have_vga = 0; + params->font_size = 16; /* XXX */ + + if (grub_le_to_cpu16 (params->version) >= 0x0206) + { + params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; + params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; +#ifdef __x86_64__ + params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); +#endif + } + else if (grub_le_to_cpu16 (params->version) >= 0x0204) + { + params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; + params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; + } + +#if 0 + /* The structure is zeroed already. */ + + /* No VBE on EFI. */ + params->lfb_width = 0; + params->lfb_height = 0; + params->lfb_depth = 0; + params->lfb_base = 0; + params->lfb_size = 0; + params->lfb_line_len = 0; + params->red_mask_size = 0; + params->red_field_pos = 0; + params->green_mask_size = 0; + params->green_field_pos = 0; + params->blue_mask_size = 0; + params->blue_field_pos = 0; + params->reserved_mask_size = 0; + params->reserved_field_pos = 0; + params->vesapm_segment = 0; + params->vesapm_offset = 0; + params->lfb_pages = 0; + params->vesa_attrib = 0; + + /* No APM on EFI. */ + params->apm_version = 0; + params->apm_code_segment = 0; + params->apm_entry = 0; + params->apm_16bit_code_segment = 0; + params->apm_data_segment = 0; + params->apm_flags = 0; + params->apm_code_len = 0; + params->apm_data_len = 0; + + /* XXX is there any way to use SpeedStep on EFI? */ + params->ist_signature = 0; + params->ist_command = 0; + params->ist_event = 0; + params->ist_perf_level = 0; + + /* Let the kernel probe the information. */ + grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info)); + grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info)); + + /* No MCA on EFI. */ + params->rom_config_len = 0; + + /* No need to fake the BIOS's memory map. */ + params->mmap_size = 0; + + /* Let the kernel probe the information. */ + params->ps_mouse = 0; + + /* Clear padding for future compatibility. */ + grub_memset (params->padding1, 0, sizeof (params->padding1)); + grub_memset (params->padding2, 0, sizeof (params->padding2)); + grub_memset (params->padding3, 0, sizeof (params->padding3)); + grub_memset (params->padding4, 0, sizeof (params->padding4)); + grub_memset (params->padding5, 0, sizeof (params->padding5)); + grub_memset (params->padding6, 0, sizeof (params->padding6)); + grub_memset (params->padding7, 0, sizeof (params->padding7)); + grub_memset (params->padding8, 0, sizeof (params->padding8)); + grub_memset (params->padding9, 0, sizeof (params->padding9)); + +#endif + + /* The other EFI parameters are filled when booting. */ + + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + + /* XXX there is no way to know if the kernel really supports EFI. */ + grub_printf (" [Linux-bzImage, setup=0x%x, size=0x%x]\n", + (unsigned) real_size, (unsigned) prot_size); + + /* Detect explicitly specified memory size, if any. */ + linux_mem_size = 0; + video_type = 0; + for (i = 1; i < argc; i++) + if (grub_memcmp (argv[i], "mem=", 4) == 0) + { + char *val = argv[i] + 4; + + linux_mem_size = grub_strtoul (val, &val, 0); + + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + linux_mem_size = 0; + } + else + { + int shift = 0; + + switch (grub_tolower (val[0])) + { + case 'g': + shift += 10; + case 'm': + shift += 10; + case 'k': + shift += 10; + default: + break; + } + + /* Check an overflow. */ + if (linux_mem_size > (~0UL >> shift)) + linux_mem_size = 0; + else + linux_mem_size <<= shift; + } + } + else if (grub_memcmp (argv[i], "video=", 6) == 0) + { + if (grub_memcmp (&argv[i][6], "vesafb", 6) == 0) + video_type = GRUB_VIDEO_TYPE_VLFB; + else if (grub_memcmp (&argv[i][6], "efifb", 5) == 0) + video_type = GRUB_VIDEO_TYPE_EFI; + } + + if (video_type) + { + if (! grub_linux_setup_video (params)) + params->have_vga = video_type; + } + + /* Specify the boot file. */ + dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET, + "BOOT_IMAGE="); + dest = grub_stpcpy (dest, argv[0]); + + /* Copy kernel parameters. */ + for (i = 1; + i < argc + && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem + + GRUB_LINUX_CL_END_OFFSET); + i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + + len = prot_size; + if (grub_file_read (file, (char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + loaded = 1; + } + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_efi_uintn_t mmap_size; + grub_efi_memory_descriptor_t *desc; + grub_efi_uintn_t desc_size; + struct linux_kernel_header *lh; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (! loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + size = grub_file_size (file); + initrd_pages = (page_align (size) >> 12); + + lh = (struct linux_kernel_header *) real_mode_mem; + + addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10); + if (linux_mem_size != 0 && linux_mem_size < addr_max) + addr_max = linux_mem_size; + + /* Linux 2.3.xx has a bug in the memory range check, so avoid + the last page. + Linux 2.2.xx has a bug in the memory range check, which is + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + + /* Usually, the compression ratio is about 50%. */ + addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12) + + page_align (size); + + /* Find the highest address to put the initrd. */ + mmap_size = find_mmap_size (); + if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0) + grub_fatal ("cannot get memory map"); + + addr = 0; + for (desc = mmap_buf; + desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY + && desc->num_pages >= initrd_pages) + { + grub_efi_physical_address_t physical_end; + + physical_end = desc->physical_start + (desc->num_pages << 12); + if (physical_end > addr_max) + physical_end = addr_max; + + if (physical_end < addr_min) + continue; + + if (physical_end > addr) + addr = physical_end - page_align (size); + } + } + + if (addr == 0) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available"); + goto fail; + } + + initrd_mem = grub_efi_allocate_pages (addr, initrd_pages); + if (! initrd_mem) + grub_fatal ("cannot allocate pages"); + + if (grub_file_read (file, initrd_mem, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n", + (unsigned) addr, (unsigned) size); + + lh->ramdisk_image = addr; + lh->ramdisk_size = size; + lh->root_dev = 0x0100; /* XXX */ + + fail: + if (file) + grub_file_close (file); +} + + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", + grub_rescue_cmd_linux, + "load linux"); + grub_rescue_register_command ("initrd", + grub_rescue_cmd_initrd, + "load initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); +} diff --git a/loader/i386/ieee1275/linux.c b/loader/i386/ieee1275/linux.c new file mode 100644 index 0000000..d01349b --- /dev/null +++ b/loader/i386/ieee1275/linux.c @@ -0,0 +1,283 @@ +/* linux.c - boot Linux zImage or bzImage */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_OFW_LINUX_PARAMS_ADDR 0x90000 +#define GRUB_OFW_LINUX_KERNEL_ADDR 0x100000 +#define GRUB_OFW_LINUX_INITRD_ADDR 0x800000 + +#define GRUB_OFW_LINUX_CL_OFFSET 0x1e00 +#define GRUB_OFW_LINUX_CL_LENGTH 0x100 + +static grub_dl_t my_mod; + +static grub_size_t kernel_size; +static char *kernel_addr, *kernel_cmdline; +static grub_size_t initrd_size; + +static grub_err_t +grub_linux_unload (void) +{ + grub_free (kernel_cmdline); + grub_free (kernel_addr); + kernel_cmdline = 0; + kernel_addr = 0; + initrd_size = 0; + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* +static int +grub_ieee1275_debug (void) +{ + struct enter_args + { + struct grub_ieee1275_common_hdr common; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "enter", 0, 0); + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + return 0; +} +*/ + +static grub_err_t +grub_linux_boot (void) +{ + struct linux_kernel_params *params; + struct linux_kernel_header *lh; + char *prot_code; + char *bootpath; + grub_ssize_t len; + + bootpath = grub_env_get ("root"); + if (bootpath) + grub_ieee1275_set_property (grub_ieee1275_chosen, + "bootpath", bootpath, + grub_strlen (bootpath) + 1, + &len); + + params = (struct linux_kernel_params *) GRUB_OFW_LINUX_PARAMS_ADDR; + lh = (struct linux_kernel_header *) params; + + grub_memset ((char *) params, 0, GRUB_OFW_LINUX_CL_OFFSET); + + params->alt_mem = grub_upper_mem >> 10; + params->ext_mem = params->alt_mem; + + lh->cmd_line_ptr = (char *) + (GRUB_OFW_LINUX_PARAMS_ADDR + GRUB_OFW_LINUX_CL_OFFSET); + + params->cl_magic = GRUB_LINUX_CL_MAGIC; + params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET; + + params->video_width = (grub_getwh () >> 8); + params->video_height = (grub_getwh () & 0xff); + params->font_size = 16; + + params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE; + params->ofw_num_items = 1; + params->ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; + params->ofw_idt = 0; + + if (initrd_size) + { + lh->type_of_loader = 1; + lh->ramdisk_image = GRUB_OFW_LINUX_INITRD_ADDR; + lh->ramdisk_size = initrd_size; + } + + if (kernel_cmdline) + grub_strcpy (lh->cmd_line_ptr, kernel_cmdline); + + prot_code = (char *) GRUB_OFW_LINUX_KERNEL_ADDR; + grub_memcpy (prot_code, kernel_addr, kernel_size); + + asm volatile ("movl %0, %%esi" : : "m" (params)); + asm volatile ("movl %%esi, %%esp" : : ); + asm volatile ("movl %0, %%ecx" : : "m" (prot_code)); + asm volatile ("xorl %%ebx, %%ebx" : : ); + asm volatile ("jmp *%%ecx" : : ); + + return GRUB_ERR_NONE; +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_kernel_header lh; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size; + int i; + char *dest; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + if (grub_file_read (file, (char *) &lh, sizeof (lh)) != sizeof (lh)) + { + grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header"); + goto fail; + } + + if ((lh.boot_flag != grub_cpu_to_le16 (0xaa55)) || + (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE))) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + setup_sects = lh.setup_sects; + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", + "bzImage", real_size, prot_size); + + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + if (grub_errno) + goto fail; + + kernel_cmdline = grub_malloc (GRUB_OFW_LINUX_CL_LENGTH); + if (! kernel_cmdline) + goto fail; + + dest = kernel_cmdline; + for (i = 1; + i < argc + && dest + grub_strlen (argv[i]) + 1 < (kernel_cmdline + + GRUB_OFW_LINUX_CL_LENGTH); + i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + + kernel_addr = grub_malloc (prot_size); + if (! kernel_addr) + goto fail; + + kernel_size = prot_size; + if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size) + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + + if (grub_errno == GRUB_ERR_NONE) + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + +fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (kernel_cmdline); + grub_free (kernel_addr); + kernel_cmdline = 0; + kernel_addr = 0; + + grub_dl_unref (my_mod); + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (! kernel_addr) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + initrd_size = grub_file_size (file); + if (grub_file_read (file, (char *) GRUB_OFW_LINUX_INITRD_ADDR, + initrd_size) != (int) initrd_size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + +fail: + if (file) + grub_file_close (file); +} + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", + grub_rescue_cmd_linux, + "load linux"); + grub_rescue_register_command ("initrd", + grub_rescue_cmd_initrd, + "load initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); +} diff --git a/loader/i386/linux.c b/loader/i386/linux.c new file mode 100644 index 0000000..a5fbf04 --- /dev/null +++ b/loader/i386/linux.c @@ -0,0 +1,606 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_LINUX_CL_OFFSET 0x1000 +#define GRUB_LINUX_CL_END_OFFSET 0x2000 + +static grub_dl_t my_mod; + +static grub_size_t linux_mem_size; +static int loaded; +static void *real_mode_mem; +static void *prot_mode_mem; +static void *initrd_mem; +static grub_uint32_t real_mode_pages; +static grub_uint32_t prot_mode_pages; +static grub_uint32_t initrd_pages; + +static grub_uint8_t gdt[] __attribute__ ((aligned(16))) = + { + /* NULL. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Reserved. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* Code segment. */ + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00, + /* Data segment. */ + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + }; + +struct gdt_descriptor +{ + grub_uint16_t limit; + void *base; +} __attribute__ ((packed)); + +static struct gdt_descriptor gdt_desc = + { + sizeof (gdt) - 1, + gdt + }; + +struct idt_descriptor +{ + grub_uint16_t limit; + void *base; +} __attribute__ ((packed)); + +static struct idt_descriptor idt_desc = + { + 0, + 0 + }; + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Find the optimal number of pages for the memory map. */ +static grub_size_t +find_mmap_size (void) +{ + grub_size_t count = 0, mmap_size; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + grub_machine_mmap_iterate (hook); + + mmap_size = count * sizeof (struct grub_e820_mmap); + + /* Increase the size a bit for safety, because GRUB allocates more on + later. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + +static void +free_pages (void) +{ + real_mode_mem = prot_mode_mem = initrd_mem = 0; +} + +/* Allocate pages for the real mode code and the protected mode code + for linux as well as a memory map buffer. */ +static int +allocate_pages (grub_size_t prot_size) +{ + grub_size_t real_size, mmap_size; + + /* Make sure that each size is aligned to a page boundary. */ + real_size = GRUB_LINUX_CL_END_OFFSET; + prot_size = page_align (prot_size); + mmap_size = find_mmap_size (); + + grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n", + (unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size); + + /* Calculate the number of pages; Combine the real mode code with + the memory map buffer for simplicity. */ + real_mode_pages = ((real_size + mmap_size) >> 12); + prot_mode_pages = (prot_size >> 12); + + /* Initialize the memory pointers with NULL for convenience. */ + real_mode_mem = 0; + prot_mode_mem = 0; + +#ifdef GRUB_MACHINE_PCBIOS +#error i386-pc port adds lower memory to heap, which collides with `real_mode_mem' allocation below +#endif + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + /* We must put real mode code in the traditional space. */ + + if (type == GRUB_MACHINE_MEMORY_AVAILABLE + && addr <= 0x90000) + { + if (addr < 0x10000) + { + size += addr - 0x10000; + addr = 0x10000; + } + + if (addr + size > 0x90000) + size = 0x90000 - addr; + + if (real_size + mmap_size > size) + return 0; + + real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size)); + return 1; + } + + return 0; + } + grub_machine_mmap_iterate (hook); + if (! real_mode_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + goto fail; + } + + prot_mode_mem = (void *) 0x100000; + + grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, " + "prot_mode_mem = %lx, prot_mode_pages = %x\n", + (unsigned long) real_mode_mem, (unsigned) real_mode_pages, + (unsigned long) prot_mode_mem, (unsigned) prot_mode_pages); + + return 1; + + fail: + free_pages (); + return 0; +} + +static void +grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, + grub_uint64_t start, grub_uint64_t size, + grub_uint32_t type) +{ + int n = *e820_num; + + if (n >= GRUB_E820_MAX_ENTRY) + grub_fatal ("Too many e820 memory map entries"); + + if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && + (e820_map[n - 1].type == type)) + e820_map[n - 1].size += size; + else + { + e820_map[n].addr = start; + e820_map[n].size = size; + e820_map[n].type = type; + (*e820_num)++; + } +} + +#ifdef __x86_64__ +struct +{ + grub_uint32_t kernel_entry; + grub_uint32_t kernel_cs; +} jumpvector; +#endif + +static grub_err_t +grub_linux32_boot (void) +{ + struct linux_kernel_params *params; + int e820_num; + + params = real_mode_mem; + + grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n", + (unsigned) params->code32_start, + (unsigned long) &(idt_desc.limit), + (unsigned long) &(gdt_desc.limit)); + grub_dprintf ("linux", "idt = %x:%lx, gdt = %x:%lx\n", + (unsigned) idt_desc.limit, (unsigned long) idt_desc.base, + (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base); + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_RAM); + break; + + default: + grub_e820_add_region (params->e820_map, &e820_num, + addr, size, GRUB_E820_RESERVED); + } + return 0; + } + + e820_num = 0; + grub_machine_mmap_iterate (hook); + params->mmap_size = e820_num; + + /* Hardware interrupts are not safe any longer. */ + asm volatile ("cli" : : ); + + /* Load the IDT and the GDT for the bootstrap. */ + asm volatile ("lidt %0" : : "m" (idt_desc)); + asm volatile ("lgdt %0" : : "m" (gdt_desc)); + +#ifdef __x86_64__ + + jumpvector.kernel_entry = (grub_uint64_t) grub_linux_real_boot; + jumpvector.kernel_cs = 0x10; + + asm volatile ( "mov %0, %%rbx" : : "m" (params->code32_start)); + asm volatile ( "mov %0, %%rsi" : : "m" (real_mode_mem)); + + asm volatile ( "ljmp *%0" : : "m" (jumpvector)); + +#else + + /* Pass parameters. */ + asm volatile ("movl %0, %%ecx" : : "m" (params->code32_start)); + asm volatile ("movl %0, %%esi" : : "m" (real_mode_mem)); + + asm volatile ("xorl %%ebx, %%ebx" : : ); + + /* Enter Linux. */ + asm volatile ("jmp *%%ecx" : : ); + +#endif + + /* Never reach here. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + free_pages (); + grub_dl_unref (my_mod); + loaded = 0; + return GRUB_ERR_NONE; +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_kernel_header lh; + struct linux_kernel_params *params; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size; + grub_ssize_t len; + int i; + char *dest; + int video_type; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + if (grub_file_read (file, (char *) &lh, sizeof (lh)) != sizeof (lh)) + { + grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header"); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, "too many setup sectors"); + goto fail; + } + + /* FIXME: Is 2.02 recent enough for 32-bit boot? */ + if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) + || grub_le_to_cpu16 (lh.version) < 0x0203) + { + grub_error (GRUB_ERR_BAD_OS, "too old version"); + goto fail; + } + + /* zImage doesn't support 32-bit boot. */ + if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) + { + grub_error (GRUB_ERR_BAD_OS, "zImage is not supported"); + goto fail; + } + + setup_sects = lh.setup_sects; + + /* If SETUP_SECTS is not set, set it to the default (4). */ + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + if (! allocate_pages (prot_size)) + goto fail; + + params = (struct linux_kernel_params *) real_mode_mem; + grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET); + grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); + + params->ps_mouse = params->padding10 = 0; + + len = 0x400 - sizeof (lh); + if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4); + + params->cl_magic = GRUB_LINUX_CL_MAGIC; + params->cl_offset = 0x1000; + params->cmd_line_ptr = (unsigned long) real_mode_mem + 0x1000; + params->ramdisk_image = 0; + params->ramdisk_size = 0; + + params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; + params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + + /* These are not needed to be precise, because Linux uses these values + only to raise an error when the decompression code cannot find good + space. */ + params->ext_mem = ((32 * 0x100000) >> 10); + params->alt_mem = ((32 * 0x100000) >> 10); + + params->video_cursor_x = grub_getxy () >> 8; + params->video_cursor_y = grub_getxy () & 0xff; + params->video_page = 0; /* ??? */ + params->video_mode = 0; + params->video_width = (grub_getwh () >> 8); + params->video_ega_bx = 0; + params->video_height = (grub_getwh () & 0xff); + params->have_vga = 0; + params->font_size = 16; /* XXX */ + + /* The other parameters are filled when booting. */ + + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + + grub_printf (" [Linux-bzImage, setup=0x%x, size=0x%x]\n", + (unsigned) real_size, (unsigned) prot_size); + + /* Detect explicitly specified memory size, if any. */ + linux_mem_size = 0; + video_type = 0; + for (i = 1; i < argc; i++) + if (grub_memcmp (argv[i], "mem=", 4) == 0) + { + char *val = argv[i] + 4; + + linux_mem_size = grub_strtoul (val, &val, 0); + + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + linux_mem_size = 0; + } + else + { + int shift = 0; + + switch (grub_tolower (val[0])) + { + case 'g': + shift += 10; + case 'm': + shift += 10; + case 'k': + shift += 10; + default: + break; + } + + /* Check an overflow. */ + if (linux_mem_size > (~0UL >> shift)) + linux_mem_size = 0; + else + linux_mem_size <<= shift; + } + } + + /* Specify the boot file. */ + dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET, + "BOOT_IMAGE="); + dest = grub_stpcpy (dest, argv[0]); + + /* Copy kernel parameters. */ + for (i = 1; + i < argc + && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem + + GRUB_LINUX_CL_END_OFFSET); + i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + + len = prot_size; + if (grub_file_read (file, (char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux32_boot, grub_linux_unload, 1); + loaded = 1; + } + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + struct linux_kernel_header *lh; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (! loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + size = grub_file_size (file); + initrd_pages = (page_align (size) >> 12); + + lh = (struct linux_kernel_header *) real_mode_mem; + + /* Get the highest address available for the initrd. */ + if (grub_le_to_cpu16 (lh->version) >= 0x0203) + { + addr_max = grub_cpu_to_le32 (lh->initrd_addr_max); + + /* XXX in reality, Linux specifies a bogus value, so + it is necessary to make sure that ADDR_MAX does not exceed + 0x3fffffff. */ + if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS) + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + } + else + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + + if (linux_mem_size != 0 && linux_mem_size < addr_max) + addr_max = linux_mem_size; + + /* Linux 2.3.xx has a bug in the memory range check, so avoid + the last page. + Linux 2.2.xx has a bug in the memory range check, which is + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + + /* Usually, the compression ratio is about 50%. */ + addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12) + + page_align (size); + + if (addr_max > grub_os_area_addr + grub_os_area_size) + addr_max = grub_os_area_addr + grub_os_area_size; + + /* Put the initrd as high as possible, 4KiB aligned. */ + addr = (addr_max - size) & ~0xFFF; + + if (addr < addr_min) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big"); + goto fail; + } + + initrd_mem = (void *) addr; + + if (grub_file_read (file, initrd_mem, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n", + (unsigned) addr, (unsigned) size); + + lh->ramdisk_image = addr; + lh->ramdisk_size = size; + lh->root_dev = 0x0100; /* XXX */ + + fail: + if (file) + grub_file_close (file); +} + + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", + grub_rescue_cmd_linux, + "load linux"); + grub_rescue_register_command ("initrd", + grub_rescue_cmd_initrd, + "load initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); +} diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c new file mode 100644 index 0000000..825dbb3 --- /dev/null +++ b/loader/i386/pc/chainloader.c @@ -0,0 +1,164 @@ +/* chainloader.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_dl_t my_mod; +static int boot_drive; +static void *boot_part_addr; + +static grub_err_t +grub_chainloader_boot (void) +{ + grub_chainloader_real_boot (boot_drive, boot_part_addr); + + /* Never reach here. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_chainloader_unload (void) +{ + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +} + +void +grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) +{ + grub_file_t file = 0; + grub_uint16_t signature; + grub_device_t dev; + int drive = -1; + void *part_addr = 0; + + grub_dl_ref (my_mod); + + file = grub_file_open (filename); + if (! file) + goto fail; + + /* Read the first block. */ + if (grub_file_read (file, (char *) 0x7C00, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_OS, "too small"); + + goto fail; + } + + /* Check the signature. */ + signature = *((grub_uint16_t *) (0x7C00 + GRUB_DISK_SECTOR_SIZE - 2)); + if (signature != grub_le_to_cpu16 (0xaa55) + && ! (flags & GRUB_CHAINLOADER_FORCE)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid signature"); + goto fail; + } + + grub_file_close (file); + + /* Obtain the partition table from the root device. */ + dev = grub_device_open (0); + if (dev) + { + grub_disk_t disk = dev->disk; + + if (disk) + { + grub_partition_t p = disk->partition; + + /* In i386-pc, the id is equal to the BIOS drive number. */ + drive = (int) disk->id; + + if (p) + { + grub_disk_read (disk, p->offset, 446, 64, + (char *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); + part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + + (p->index << 4)); + } + } + + grub_device_close (dev); + } + + /* Ignore errors. Perhaps it's not fatal. */ + grub_errno = GRUB_ERR_NONE; + + boot_drive = drive; + boot_part_addr = part_addr; + + grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1); + return; + + fail: + + if (file) + grub_file_close (file); + + grub_dl_unref (my_mod); +} + +static void +grub_rescue_cmd_chainloader (int argc, char *argv[]) +{ + grub_chainloader_flags_t flags = 0; + + if (argc > 0 && grub_strcmp (argv[0], "--force") == 0) + { + flags |= GRUB_CHAINLOADER_FORCE; + argc--; + argv++; + } + + if (argc == 0) + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + else + grub_chainloader_cmd (argv[0], flags); +} + +static const char loader_name[] = "chainloader"; + +GRUB_MOD_INIT(chainloader) +{ + grub_rescue_register_command (loader_name, + grub_rescue_cmd_chainloader, + "load another boot loader"); + my_mod = mod; +} + +GRUB_MOD_FINI(chainloader) +{ + grub_rescue_unregister_command (loader_name); +} diff --git a/loader/i386/pc/chainloader_normal.c b/loader/i386/pc/chainloader_normal.c new file mode 100644 index 0000000..106cd56 --- /dev/null +++ b/loader/i386/pc/chainloader_normal.c @@ -0,0 +1,56 @@ +/* chainloader_normal.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"force", 'f', 0, "skip bootsector magic number test", 0, 0}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +chainloader_command (struct grub_arg_list *state, + int argc, char **args) +{ + grub_chainloader_flags_t flags = state[0].set ? GRUB_CHAINLOADER_FORCE : 0; + + if (argc == 0) + grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified"); + else + grub_chainloader_cmd (args[0], flags); + return grub_errno; +} + +GRUB_MOD_INIT(chainloader_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("chainloader", chainloader_command, + GRUB_COMMAND_FLAG_BOTH, + "chainloader [-f] FILE", + "Prepare to boot another boot loader.", options); +} + +GRUB_MOD_FINI(chainloader_normal) +{ + grub_unregister_command ("chainloader"); +} diff --git a/loader/i386/pc/linux.c b/loader/i386/pc/linux.c new file mode 100644 index 0000000..d34b5d7 --- /dev/null +++ b/loader/i386/pc/linux.c @@ -0,0 +1,389 @@ +/* linux.c - boot Linux zImage or bzImage */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_LINUX_CL_OFFSET 0x9000 +#define GRUB_LINUX_CL_END_OFFSET 0x90FF + +static grub_dl_t my_mod; + +static grub_size_t linux_mem_size; +static int loaded; + +static grub_err_t +grub_linux_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + return GRUB_ERR_NONE; +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_kernel_header lh; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size; + grub_ssize_t len; + int i; + char *dest; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + if ((grub_size_t) grub_file_size (file) > grub_os_area_size) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)", + (grub_size_t) grub_file_size (file), + grub_os_area_size); + goto fail; + } + + if (grub_file_read (file, (char *) &lh, sizeof (lh)) != sizeof (lh)) + { + grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header"); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, "too many setup sectors"); + goto fail; + } + + grub_linux_is_bzimage = 0; + setup_sects = lh.setup_sects; + linux_mem_size = 0; + + if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) + && grub_le_to_cpu16 (lh.version) >= 0x0200) + { + grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL); + lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + + /* Put the real mode part at as a high location as possible. */ + grub_linux_real_addr = (char *) (grub_lower_mem + - GRUB_LINUX_SETUP_MOVE_SIZE); + /* But it must not exceed the traditional area. */ + if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR) + grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR; + + if (grub_le_to_cpu16 (lh.version) >= 0x0201) + { + lh.heap_end_ptr = grub_cpu_to_le16 (GRUB_LINUX_HEAP_END_OFFSET); + lh.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + } + + if (grub_le_to_cpu16 (lh.version) >= 0x0202) + lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET; + else + { + lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC); + lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET); + lh.setup_move_size = grub_cpu_to_le16 (GRUB_LINUX_SETUP_MOVE_SIZE); + } + } + else + { + /* Your kernel is quite old... */ + lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC); + lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET); + + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR; + } + + /* If SETUP_SECTS is not set, set it to the default (4). */ + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size; + + if (! grub_linux_is_bzimage + && ((char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size > grub_linux_real_addr)) + { + grub_error (GRUB_ERR_BAD_OS, "too big zImage (0x%x > 0x%x), use bzImage instead", + (char *) GRUB_LINUX_ZIMAGE_ADDR + prot_size, + (grub_size_t) grub_linux_real_addr); + goto fail; + } + + if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE + > (char *) grub_lower_mem) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + "too small lower memory (0x%x > 0x%x)", + grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE, + (char *) grub_lower_mem); + goto fail; + } + + grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", + grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, prot_size); + + for (i = 1; i < argc; i++) + if (grub_memcmp (argv[i], "vga=", 4) == 0) + { + /* Video mode selection support. */ + grub_uint16_t vid_mode; + char *val = argv[i] + 4; + + if (grub_strcmp (val, "normal") == 0) + vid_mode = GRUB_LINUX_VID_MODE_NORMAL; + else if (grub_strcmp (val, "ext") == 0) + vid_mode = GRUB_LINUX_VID_MODE_EXTENDED; + else if (grub_strcmp (val, "ask") == 0) + vid_mode = GRUB_LINUX_VID_MODE_ASK; + else + vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0); + + if (grub_errno) + goto fail; + + lh.vid_mode = grub_cpu_to_le16 (vid_mode); + } + else if (grub_memcmp (argv[i], "mem=", 4) == 0) + { + char *val = argv[i] + 4; + + linux_mem_size = grub_strtoul (val, &val, 0); + + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + linux_mem_size = 0; + } + else + { + int shift = 0; + + switch (grub_tolower (val[0])) + { + case 'g': + shift += 10; + case 'm': + shift += 10; + case 'k': + shift += 10; + default: + break; + } + + /* Check an overflow. */ + if (linux_mem_size > (~0UL >> shift)) + linux_mem_size = 0; + else + linux_mem_size <<= shift; + } + } + + /* Put the real mode code at the temporary address. */ + grub_memmove (grub_linux_tmp_addr, &lh, sizeof (lh)); + + len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); + if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) + || grub_le_to_cpu16 (lh.version) < 0x0200) + /* Clear the heap space. */ + grub_memset (grub_linux_tmp_addr + + ((setup_sects + 1) << GRUB_DISK_SECTOR_BITS), + 0, + ((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1) + << GRUB_DISK_SECTOR_BITS)); + + /* Specify the boot file. */ + dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET, + "BOOT_IMAGE="); + dest = grub_stpcpy (dest, argv[0]); + + /* Copy kernel parameters. */ + for (i = 1; + i < argc + && dest + grub_strlen (argv[i]) + 1 < (grub_linux_tmp_addr + + GRUB_LINUX_CL_END_OFFSET); + i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + + len = prot_size; + if (grub_file_read (file, (char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + + if (grub_errno == GRUB_ERR_NONE) + { + grub_linux_prot_size = prot_size; + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + loaded = 1; + } + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_addr_t addr_max, addr_min, addr; + struct linux_kernel_header *lh; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + lh = (struct linux_kernel_header *) grub_linux_tmp_addr; + + if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) + && grub_le_to_cpu16 (lh->version) >= 0x0200)) + { + grub_error (GRUB_ERR_BAD_OS, "The kernel is too old for initrd."); + goto fail; + } + + /* Get the highest address available for the initrd. */ + if (grub_le_to_cpu16 (lh->version) >= 0x0203) + { + addr_max = grub_cpu_to_le32 (lh->initrd_addr_max); + + /* XXX in reality, Linux specifies a bogus value, so + it is necessary to make sure that ADDR_MAX does not exceed + 0x3fffffff. */ + if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS) + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + } + else + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + + if (linux_mem_size != 0 && linux_mem_size < addr_max) + addr_max = linux_mem_size; + + /* Linux 2.3.xx has a bug in the memory range check, so avoid + the last page. + Linux 2.2.xx has a bug in the memory range check, which is + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + + if (addr_max > grub_os_area_addr + grub_os_area_size) + addr_max = grub_os_area_addr + grub_os_area_size; + + addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET; + + file = grub_file_open (argv[0]); + if (!file) + goto fail; + + size = grub_file_size (file); + + /* Put the initrd as high as possible, 4KiB aligned. */ + addr = (addr_max - size) & ~0xFFF; + + if (addr < addr_min) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big"); + goto fail; + } + + if (grub_file_read (file, (void *)addr, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + lh->ramdisk_image = addr; + lh->ramdisk_size = size; + + fail: + if (file) + grub_file_close (file); +} + + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", + grub_rescue_cmd_linux, + "load linux"); + grub_rescue_register_command ("initrd", + grub_rescue_cmd_initrd, + "load initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); +} diff --git a/loader/i386/pc/multiboot.c b/loader/i386/pc/multiboot.c new file mode 100644 index 0000000..c0d1fe1 --- /dev/null +++ b/loader/i386/pc/multiboot.c @@ -0,0 +1,628 @@ +/* multiboot.c - boot a multiboot OS image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * FIXME: The following features from the Multiboot specification still + * need to be implemented: + * - VBE support + * - symbol table + * - drives table + * - ROM configuration table + * - APM table + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern grub_dl_t my_mod; +static struct grub_multiboot_info *mbi; +static grub_addr_t entry; + +static char *playground = NULL; + +static grub_err_t +grub_multiboot_boot (void) +{ + grub_multiboot_real_boot (entry, mbi); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_multiboot_unload (void) +{ + if (mbi) + { + unsigned int i; + for (i = 0; i < mbi->mods_count; i++) + { + grub_free ((void *) + ((struct grub_mod_list *) mbi->mods_addr)[i].mod_start); + grub_free ((void *) + ((struct grub_mod_list *) mbi->mods_addr)[i].cmdline); + } + grub_free ((void *) mbi->mods_addr); + grub_free ((void *) mbi->cmdline); + grub_free (mbi); + } + + mbi = 0; + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* Return the length of the Multiboot mmap that will be needed to allocate + our platform's map. */ +static grub_uint32_t +grub_get_multiboot_mmap_len (void) +{ + grub_size_t count = 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + grub_machine_mmap_iterate (hook); + + return count * sizeof (struct grub_multiboot_mmap_entry); +} + +/* Fill previously allocated Multiboot mmap. */ +static void +grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry) +{ + struct grub_multiboot_mmap_entry *mmap_entry = (struct grub_multiboot_mmap_entry *) first_entry; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + mmap_entry->addr = addr; + mmap_entry->len = size; + mmap_entry->type = type; + mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size); + mmap_entry++; + + return 0; + } + + grub_machine_mmap_iterate (hook); +} + +/* Check if BUFFER contains ELF32. */ +static int +grub_multiboot_is_elf32 (void *buffer) +{ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer; + + return ehdr->e_ident[EI_CLASS] == ELFCLASS32; +} + +static grub_err_t +grub_multiboot_load_elf32 (grub_file_t file, void *buffer) +{ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer; + char *phdr_base; + int lowest_segment = 0, highest_segment = 0; + int i; + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class"); + + if (grub_dl_check_header (ehdr, sizeof(Elf32_Ehdr))) + return grub_error (GRUB_ERR_UNKNOWN_OS, "no valid ELF header found"); + + if (ehdr->e_type != ET_EXEC) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type"); + + /* FIXME: Should we support program headers at strange locations? */ + if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) + return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); + + phdr_base = (char *) buffer + ehdr->e_phoff; +#define phdr(i) ((Elf32_Phdr *) (phdr_base + (i) * ehdr->e_phentsize)) + + for (i = 0; i < ehdr->e_phnum; i++) + if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0) + { + if (phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr) + lowest_segment = i; + if (phdr(i)->p_paddr > phdr(highest_segment)->p_paddr) + highest_segment = i; + } + grub_multiboot_payload_size += (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr; + grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr; + + playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); + if (! playground) + return grub_errno; + + grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + + /* Load every loadable segment in memory. */ + for (i = 0; i < ehdr->e_phnum; i++) + { + if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0) + { + char *load_this_module_at = (char *) (grub_multiboot_payload_orig + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr)); + + grub_dprintf ("multiboot_loader", "segment %d: paddr=%p, memsz=0x%x\n", + i, (void *) phdr(i)->p_paddr, phdr(i)->p_memsz); + + if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset) + == (grub_off_t) -1) + return grub_error (GRUB_ERR_BAD_OS, + "invalid offset in program header"); + + if (grub_file_read (file, load_this_module_at, phdr(i)->p_filesz) + != (grub_ssize_t) phdr(i)->p_filesz) + return grub_error (GRUB_ERR_BAD_OS, + "couldn't read segment from file"); + + if (phdr(i)->p_filesz < phdr(i)->p_memsz) + grub_memset (load_this_module_at + phdr(i)->p_filesz, 0, + phdr(i)->p_memsz - phdr(i)->p_filesz); + } + } + + grub_multiboot_payload_entry_offset = ehdr->e_entry - phdr(lowest_segment)->p_vaddr; + +#undef phdr + + return grub_errno; +} + +/* Check if BUFFER contains ELF64. */ +static int +grub_multiboot_is_elf64 (void *buffer) +{ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer; + + return ehdr->e_ident[EI_CLASS] == ELFCLASS64; +} + +static grub_err_t +grub_multiboot_load_elf64 (grub_file_t file, void *buffer) +{ + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer; + char *phdr_base; + grub_addr_t physical_entry_addr = 0; + int i; + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class"); + + if (ehdr->e_ident[EI_MAG0] != ELFMAG0 + || ehdr->e_ident[EI_MAG1] != ELFMAG1 + || ehdr->e_ident[EI_MAG2] != ELFMAG2 + || ehdr->e_ident[EI_MAG3] != ELFMAG3 + || ehdr->e_version != EV_CURRENT + || ehdr->e_ident[EI_DATA] != ELFDATA2LSB + || ehdr->e_machine != EM_X86_64) + return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found"); + + if (ehdr->e_type != ET_EXEC) + return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type"); + + /* FIXME: Should we support program headers at strange locations? */ + if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) + return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); + + /* We still in 32-bit mode */ + if (ehdr->e_entry > 0xffffffff) + return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); + + entry = ehdr->e_entry; + + phdr_base = (char *) buffer + ehdr->e_phoff; +#define phdr(i) ((Elf64_Phdr *) (phdr_base + (i) * ehdr->e_phentsize)) + + /* Load every loadable segment in memory. */ + for (i = 0; i < ehdr->e_phnum; i++) + { + if (phdr(i)->p_type == PT_LOAD) + { + /* The segment should fit in the area reserved for the OS. */ + if (phdr(i)->p_paddr < (grub_uint64_t) grub_os_area_addr) + return grub_error (GRUB_ERR_BAD_OS, + "segment doesn't fit in memory reserved for the OS (0x%lx < 0x%lx)", + phdr(i)->p_paddr, (grub_uint64_t) grub_os_area_addr); + if (phdr(i)->p_paddr + phdr(i)->p_memsz + > (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size) + return grub_error (GRUB_ERR_BAD_OS, + "segment doesn't fit in memory reserved for the OS (0x%lx > 0x%lx)", + phdr(i)->p_paddr + phdr(i)->p_memsz, + (grub_uint64_t) grub_os_area_addr + (grub_uint64_t) grub_os_area_size); + + if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset) + == (grub_off_t) -1) + return grub_error (GRUB_ERR_BAD_OS, + "invalid offset in program header"); + + if (grub_file_read (file, (void *) ((grub_uint32_t) phdr(i)->p_paddr), + phdr(i)->p_filesz) + != (grub_ssize_t) phdr(i)->p_filesz) + return grub_error (GRUB_ERR_BAD_OS, + "couldn't read segment from file"); + + if (phdr(i)->p_filesz < phdr(i)->p_memsz) + grub_memset (((char *) ((grub_uint32_t) phdr(i)->p_paddr) + + phdr(i)->p_filesz), + 0, + phdr(i)->p_memsz - phdr(i)->p_filesz); + + if ((entry >= phdr(i)->p_vaddr) && + (entry < phdr(i)->p_vaddr + phdr(i)->p_memsz)) + physical_entry_addr = entry + phdr(i)->p_paddr - phdr(i)->p_vaddr; + } + } +#undef phdr + + if (physical_entry_addr) + entry = physical_entry_addr; + + return grub_errno; +} + +/* Load ELF32 or ELF64. */ +static grub_err_t +grub_multiboot_load_elf (grub_file_t file, void *buffer) +{ + if (grub_multiboot_is_elf32 (buffer)) + return grub_multiboot_load_elf32 (file, buffer); + else if (grub_multiboot_is_elf64 (buffer)) + return grub_multiboot_load_elf64 (file, buffer); + + return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); +} + +static int +grub_multiboot_get_bootdev (grub_uint32_t *bootdev) +{ + char *p; + + p = grub_env_get ("root"); + if ((p) && ((p[0] == 'h') || (p[0] == 'f')) && (p[1] == 'd') && + (p[2] >= '0') && (p[2] <= '9')) + { + grub_uint32_t bd; + + bd = (p[0] == 'h') ? 0x80 : 0; + bd += grub_strtoul (p + 2, &p, 0); + bd <<= 24; + + if ((p) && (p[0] == ',')) + { + if ((p[1] >= '0') && (p[1] <= '9')) + { + + bd += ((grub_strtoul (p + 1, &p, 0) - 1) & 0xFF) << 16; + + if ((p) && (p[0] == ',')) + p++; + } + else + bd += 0xFF0000; + + if ((p[0] >= 'a') && (p[0] <= 'z')) + bd += (p[0] - 'a') << 8; + else + bd += 0xFF00; + } + else + bd += 0xFFFF00; + + bd += 0xFF; + + *bootdev = bd; + return 1; + } + + return 0; +} + +void +grub_multiboot (int argc, char *argv[]) +{ + grub_file_t file = 0; + char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p; + struct grub_multiboot_header *header; + grub_ssize_t len; + int i; + + grub_loader_unset (); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + goto fail; + } + + len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); + if (len < 32) + { + grub_error (GRUB_ERR_BAD_OS, "File too small"); + goto fail; + } + + /* Look for the multiboot header in the buffer. The header should + be at least 12 bytes and aligned on a 4-byte boundary. */ + for (header = (struct grub_multiboot_header *) buffer; + ((char *) header <= buffer + len - 12) || (header = 0); + header = (struct grub_multiboot_header *) ((char *) header + 4)) + { + if (header->magic == MULTIBOOT_MAGIC + && !(header->magic + header->flags + header->checksum)) + break; + } + + if (header == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found"); + goto fail; + } + + if (header->flags & MULTIBOOT_UNSUPPORTED) + { + grub_error (GRUB_ERR_UNKNOWN_OS, + "Unsupported flag: 0x%x", header->flags); + goto fail; + } + + if (playground) + { + grub_free (playground); + playground = NULL; + } + + mbi = grub_malloc (sizeof (struct grub_multiboot_info)); + if (! mbi) + goto fail; + + grub_memset (mbi, 0, sizeof (struct grub_multiboot_info)); + + mbi->mmap_length = grub_get_multiboot_mmap_len (); + grub_multiboot_payload_size = mbi->mmap_length; + + if (header->flags & MULTIBOOT_AOUT_KLUDGE) + { + int offset = ((char *) header - buffer - + (header->header_addr - header->load_addr)); + int load_size = ((header->load_end_addr == 0) ? file->size - offset : + header->load_end_addr - header->load_addr); + + if (header->bss_end_addr) + grub_multiboot_payload_size += (header->bss_end_addr - header->load_addr); + else + grub_multiboot_payload_size += load_size; + grub_multiboot_payload_dest = header->load_addr; + + playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); + if (! playground) + goto fail; + + grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + + if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) + goto fail; + + grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); + if (grub_errno) + goto fail; + + if (header->bss_end_addr) + grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, + header->bss_end_addr - header->load_addr - load_size); + + grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr; + + } + else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) + goto fail; + + + grub_fill_multiboot_mmap ((struct grub_multiboot_mmap_entry *) (grub_multiboot_payload_orig + + grub_multiboot_payload_size + - mbi->mmap_length)); + + /* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated + by the spec. Is there something we can do about it? */ + mbi->mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mbi->mmap_length; + mbi->flags |= MULTIBOOT_INFO_MEM_MAP; + + if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) + { + grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward)); + entry = (grub_addr_t) playground; + } + else + { + grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size), + &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward)); + entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size; + } + + grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n", + (void *) grub_multiboot_payload_dest, + grub_multiboot_payload_size, + grub_multiboot_payload_entry_offset); + + /* Convert from bytes to kilobytes. */ + mbi->mem_lower = grub_lower_mem / 1024; + mbi->mem_upper = grub_upper_mem / 1024; + mbi->flags |= MULTIBOOT_INFO_MEMORY; + + for (i = 0, len = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + cmdline = p = grub_malloc (len); + if (! cmdline) + goto fail; + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + *(--p) = '\0'; + + mbi->flags |= MULTIBOOT_INFO_CMDLINE; + mbi->cmdline = (grub_uint32_t) cmdline; + + mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME; + mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING); + + if (grub_multiboot_get_bootdev (&mbi->boot_device)) + mbi->flags |= MULTIBOOT_INFO_BOOTDEV; + + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (cmdline); + grub_free (mbi); + grub_dl_unref (my_mod); + } +} + + +void +grub_module (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size, len = 0; + char *module = 0, *cmdline = 0, *p; + int i; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + goto fail; + } + + if (!mbi) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "You need to load the multiboot kernel first"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + goto fail; + + size = grub_file_size (file); + module = grub_memalign (MULTIBOOT_MOD_ALIGN, size); + if (! module) + goto fail; + + if (grub_file_read (file, module, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + cmdline = p = grub_malloc (len); + if (! cmdline) + goto fail; + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + *(--p) = '\0'; + + if (mbi->flags & MULTIBOOT_INFO_MODS) + { + struct grub_mod_list *modlist = (struct grub_mod_list *) mbi->mods_addr; + + modlist = grub_realloc (modlist, (mbi->mods_count + 1) + * sizeof (struct grub_mod_list)); + if (! modlist) + goto fail; + mbi->mods_addr = (grub_uint32_t) modlist; + modlist += mbi->mods_count; + modlist->mod_start = (grub_uint32_t) module; + modlist->mod_end = (grub_uint32_t) module + size; + modlist->cmdline = (grub_uint32_t) cmdline; + modlist->pad = 0; + mbi->mods_count++; + } + else + { + struct grub_mod_list *modlist = grub_malloc (sizeof (struct grub_mod_list)); + if (! modlist) + goto fail; + modlist->mod_start = (grub_uint32_t) module; + modlist->mod_end = (grub_uint32_t) module + size; + modlist->cmdline = (grub_uint32_t) cmdline; + modlist->pad = 0; + mbi->mods_count = 1; + mbi->mods_addr = (grub_uint32_t) modlist; + mbi->flags |= MULTIBOOT_INFO_MODS; + } + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_free (module); + grub_free (cmdline); + } +} diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c new file mode 100644 index 0000000..d5fe8e3 --- /dev/null +++ b/loader/i386/pc/multiboot2.c @@ -0,0 +1,101 @@ +/* multiboot2.c - boot a multiboot 2 OS image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +grub_err_t +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr) +{ + Elf32_Addr paddr = phdr->p_paddr; + + if ((paddr < grub_os_area_addr) + || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) + return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range", + paddr); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr) +{ + Elf64_Addr paddr = phdr->p_paddr; + + if ((paddr < grub_os_area_addr) + || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", + paddr); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) +{ + grub_addr_t modaddr; + + modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size); + if (! modaddr) + return grub_errno; + + *addr = modaddr; + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size) +{ + grub_free((void *) addr); + return GRUB_ERR_NONE; +} + +void +grub_mb2_arch_boot (grub_addr_t entry, void *tags) +{ + grub_multiboot2_real_boot (entry, tags); +} + +void +grub_mb2_arch_unload (struct multiboot_tag_header *tags) +{ + struct multiboot_tag_header *tag; + + /* Free all module memory in the tag list. */ + for_each_tag (tag, tags) + { + if (tag->key == MULTIBOOT2_TAG_MODULE) + { + struct multiboot_tag_module *module = + (struct multiboot_tag_module *) tag; + grub_free((void *) module->addr); + } + } +} + +grub_err_t +grub_mb2_tags_arch_create (void) +{ + /* XXX Create boot device et al. */ + return GRUB_ERR_NONE; +} diff --git a/loader/i386/pc/multiboot_normal.c b/loader/i386/pc/multiboot_normal.c new file mode 100644 index 0000000..b80568f --- /dev/null +++ b/loader/i386/pc/multiboot_normal.c @@ -0,0 +1,60 @@ +/* multiboot_normal.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_multiboot (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_module (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(multiboot_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("multiboot", grub_normal_cmd_multiboot, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "multiboot FILE [ARGS...]", + "Load a Multiboot kernel.", 0); + + grub_register_command ("module", grub_normal_cmd_module, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "module FILE [ARGS...]", + "Load a Multiboot module.", 0); +} + +GRUB_MOD_FINI(multiboot_normal) +{ + grub_unregister_command ("multiboot"); + grub_unregister_command ("module"); +} diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c new file mode 100644 index 0000000..c253fc9 --- /dev/null +++ b/loader/ieee1275/multiboot2.c @@ -0,0 +1,126 @@ +/* multiboot.c - boot a multiboot 2 OS image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef void (*kernel_entry_t) (unsigned long, void *, int (void *), + unsigned long, unsigned long); + +/* Claim the memory occupied by the multiboot kernel. */ +grub_err_t +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr) +{ + int rc; + + rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz); + if (rc) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x", + phdr->p_paddr, phdr->p_paddr + phdr->p_memsz); + + grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr, + phdr->p_paddr + phdr->p_memsz); + + return GRUB_ERR_NONE; +} + +/* Claim the memory occupied by the multiboot kernel. */ +grub_err_t +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr) +{ + int rc; + + rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz); + if (rc) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx", + phdr->p_paddr, phdr->p_paddr + phdr->p_memsz); + + grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n", + (unsigned long) phdr->p_paddr, + (unsigned long) (phdr->p_paddr + phdr->p_memsz)); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) +{ + int rc; + + /* XXX Will need to map on some firmwares. */ + rc = grub_ieee1275_claim (0, size, MULTIBOOT2_MOD_ALIGN, addr); + if (rc) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Firmware couldn't allocate memory (size 0x%lx)", size); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size) +{ + grub_ieee1275_release (addr, size); + return GRUB_ERR_NONE; +} + +grub_err_t +grub_mb2_tags_arch_create (void) +{ + /* Nothing special. */ + return GRUB_ERR_NONE; +} + +/* Release the memory we claimed from Open Firmware above. */ +void +grub_mb2_arch_unload (struct multiboot_tag_header *tags) +{ + struct multiboot_tag_header *tag; + + /* Free all module memory in the tag list. */ + for_each_tag (tag, tags) + { + if (tag->key == MULTIBOOT2_TAG_MODULE) + { + struct multiboot_tag_module *module = + (struct multiboot_tag_module *) tag; + grub_ieee1275_release (module->addr, module->size); + } + } +} + +void +grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags) +{ +#if defined(__powerpc__) + kernel_entry_t entry = (kernel_entry_t) entry_addr; + entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0); +#elif defined(__i386__) + grub_multiboot2_real_boot (entry_addr, tags); +#else +#error +#endif +} diff --git a/loader/linux_normal.c b/loader/linux_normal.c new file mode 100644 index 0000000..0d7231e --- /dev/null +++ b/loader/linux_normal.c @@ -0,0 +1,60 @@ +/* linux_normal.c - boot linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_normal_linux_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_linux (argc, args); + return grub_errno; +} + + +static grub_err_t +grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_initrd (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(linux_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("linux", grub_normal_linux_command, + GRUB_COMMAND_FLAG_BOTH, + "linux FILE [ARGS...]", + "Load a linux kernel.", 0); + + grub_register_command ("initrd", grub_normal_initrd_command, + GRUB_COMMAND_FLAG_BOTH, + "initrd FILE", + "Load an initrd.", 0); +} + +GRUB_MOD_FINI(linux_normal) +{ + grub_unregister_command ("linux"); + grub_unregister_command ("initrd"); +} diff --git a/loader/multiboot2.c b/loader/multiboot2.c new file mode 100644 index 0000000..2fb56bf --- /dev/null +++ b/loader/multiboot2.c @@ -0,0 +1,461 @@ +/* multiboot2.c - boot a multiboot 2 OS image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_addr_t entry; +extern grub_dl_t my_mod; + +static char *grub_mb2_tags; +static char *grub_mb2_tags_pos; +static grub_size_t grub_mb2_tags_len; +static int grub_mb2_tags_count; + +static void +grub_mb2_tags_free (void) +{ + grub_dprintf ("loader", "Freeing all tags...\n"); + grub_free (grub_mb2_tags); + grub_mb2_tags = 0; + grub_mb2_tags_pos = 0; + grub_mb2_tags_len = 0; + grub_mb2_tags_count = 0; +} + +grub_err_t +grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len) +{ + struct multiboot_tag_header *tag; + grub_size_t used; + grub_size_t needed; + + grub_dprintf ("loader", "Allocating tag: key 0x%x, size 0x%lx.\n", + key, (unsigned long) len); + + used = grub_mb2_tags_pos - grub_mb2_tags; + len = ALIGN_UP (len, sizeof (multiboot_word)); + + needed = used + len; + + if (needed > grub_mb2_tags_len) + { + /* Allocate new buffer. */ + grub_size_t newsize = needed * 2; + char *newarea; + + grub_dprintf ("loader", "Reallocating tag buffer (new size 0x%lx).\n", + (unsigned long) newsize); + + newarea = grub_malloc (newsize); + if (! newarea) + return grub_errno; + grub_memcpy (newarea, grub_mb2_tags, grub_mb2_tags_len); + grub_free (grub_mb2_tags); + + grub_mb2_tags_len = newsize; + grub_mb2_tags = newarea; + grub_mb2_tags_pos = newarea + used; + } + + tag = (struct multiboot_tag_header *) grub_mb2_tags_pos; + grub_mb2_tags_pos += len; + + tag->key = key; + tag->len = len; + + if (addr) + *addr = (grub_addr_t) tag; + + grub_mb2_tags_count++; + + grub_dprintf ("loader", "Allocated tag %u at %p.\n", grub_mb2_tags_count, tag); + + return 0; +} + +static grub_err_t +grub_mb2_tag_start_create (void) +{ + return grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_START, + sizeof (struct multiboot_tag_start)); +} + +static grub_err_t +grub_mb2_tag_name_create (void) +{ + struct multiboot_tag_name *name; + grub_addr_t name_addr; + grub_err_t err; + const char *grub_version = PACKAGE_STRING; + + err = grub_mb2_tag_alloc (&name_addr, MULTIBOOT2_TAG_NAME, + sizeof (struct multiboot_tag_name) + + sizeof (grub_version) + 1); + if (err) + return err; + + name = (struct multiboot_tag_name *) name_addr; + grub_strcpy (name->name, grub_version); + + return GRUB_ERR_NONE; +} + +typedef grub_err_t (*tag_create_t) (void); +static tag_create_t grub_mb2_tag_creators[] = { + grub_mb2_tag_start_create, + grub_mb2_tag_name_create, + grub_mb2_tags_arch_create, + 0, +}; + +static grub_err_t +grub_mb2_tags_create (void) +{ + tag_create_t *creator; + grub_err_t err; + + for (creator = grub_mb2_tag_creators; *creator != 0; creator++) + { + err = (*creator) (); + if (err) + goto error; + } + + return GRUB_ERR_NONE; + +error: + grub_error_push (); + grub_mb2_tags_free (); + grub_error_pop (); + return err; +} + +static grub_err_t +grub_mb2_tags_finish (void) +{ + struct multiboot_tag_start *start; + grub_err_t err; + + /* Create the `end' tag. */ + err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END, + sizeof (struct multiboot_tag_end)); + if (err) + goto error; + + /* We created the `start' tag first. Update it now. */ + start = (struct multiboot_tag_start *) grub_mb2_tags; + start->size = grub_mb2_tags_pos - grub_mb2_tags; + return GRUB_ERR_NONE; + +error: + grub_error_push (); + grub_mb2_tags_free (); + grub_error_pop (); + return err; +} + +static grub_err_t +grub_mb2_boot (void) +{ + grub_mb2_tags_finish (); + + grub_dprintf ("loader", "Tags at %p\n", grub_mb2_tags); + grub_mb2_arch_boot (entry, grub_mb2_tags); + + /* Not reached. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_mb2_unload (void) +{ + struct multiboot_tag_header *tag; + struct multiboot_tag_header *tags = + (struct multiboot_tag_header *) grub_mb2_tags; + + /* Free all module memory in the tag list. */ + for_each_tag (tag, tags) + { + if (tag->key == MULTIBOOT2_TAG_MODULE) + { + struct multiboot_tag_module *module = + (struct multiboot_tag_module *) tag; + grub_free ((void *) module->addr); + } + } + + /* Allow architecture to un-reserve memory. */ + grub_mb2_arch_unload (tags); + + /* Free the tags themselves. */ + grub_mb2_tags_free (); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer) +{ + /* XXX Create module tag here. */ + return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported"); +} + +/* Create the tag containing the cmdline and the address of the module data. */ +static grub_err_t +grub_mb2_tag_module_create (grub_addr_t modaddr, grub_size_t modsize, + char *type, int key, int argc, char *argv[]) +{ + struct multiboot_tag_module *module; + grub_ssize_t argslen = 0; + grub_err_t err; + char *p; + grub_addr_t module_addr; + int i; + + /* Allocate enough space for the arguments and spaces between them. */ + for (i = 0; i < argc; i++) + argslen += grub_strlen (argv[i]) + 1; + + /* Note: includes implicit 1-byte cmdline. */ + err = grub_mb2_tag_alloc (&module_addr, key, + sizeof (struct multiboot_tag_module) + argslen); + if (err) + return grub_errno; + + module = (struct multiboot_tag_module *) module_addr; + module->addr = modaddr; + module->size = modsize; + grub_strcpy(module->type, type); + + /* Fill in the command line. */ + p = module->cmdline; + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *p++ = ' '; + } + module->cmdline[argslen] = '\0'; + + return GRUB_ERR_NONE; +} + +/* Load ELF32 or ELF64. */ +static grub_err_t +grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[]) +{ + grub_addr_t kern_base; + grub_size_t kern_size; + grub_err_t err; + + if (grub_elf_is_elf32 (elf)) + { + entry = elf->ehdr.ehdr32.e_entry; + err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base, + &kern_size); + } + else if (grub_elf_is_elf64 (elf)) + { + entry = elf->ehdr.ehdr64.e_entry; + err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base, + &kern_size); + } + else + err = grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); + + if (err) + goto fail; + + grub_dprintf ("loader", "Entry point is 0x%lx.\n", (unsigned long) entry); + + grub_mb2_tag_module_create (kern_base, kern_size, "kernel", + MULTIBOOT2_TAG_MODULE, argc, argv); + +fail: + return err; +} + +void +grub_multiboot2 (int argc, char *argv[]) +{ + char *buffer; + grub_file_t file = 0; + grub_elf_t elf = 0; + struct multiboot_header *header = 0; + char *p; + grub_ssize_t len; + grub_err_t err; + int header_found = 0; + + grub_loader_unset (); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + goto fail; + } + + buffer = grub_malloc (MULTIBOOT2_HEADER_SEARCH); + if (! buffer) + return; + + len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH); + if (len < 32) + { + grub_error (GRUB_ERR_BAD_OS, "File too small"); + goto fail; + } + + /* Look for the multiboot header in the buffer. The header should + be at least 8 bytes and aligned on a 8-byte boundary. */ + for (p = buffer; p <= buffer + len - 8; p += 8) + { + header = (struct multiboot_header *) p; + if (header->magic == MULTIBOOT2_HEADER_MAGIC) + { + header_found = 1; + break; + } + } + + if (! header_found) + grub_dprintf ("loader", "No multiboot 2 header found.\n"); + + + /* Create the basic tags. */ + grub_dprintf ("loader", "Creating multiboot 2 tags\n"); + grub_mb2_tags_create (); + + /* Load the kernel and create its tag. */ + elf = grub_elf_file (file); + if (elf) + { + grub_dprintf ("loader", "Loading ELF multiboot 2 file.\n"); + err = grub_mb2_load_elf (elf, argc-1, &argv[1]); + grub_elf_close (elf); + } + else + { + grub_errno = 0; + grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n"); + + if (header) + err = grub_mb2_load_other (file, header); + else + err = grub_error (GRUB_ERR_BAD_OS, + "Need multiboot 2 header to load non-ELF files."); + grub_file_close (file); + } + + grub_free (buffer); + + if (err) + goto fail; + + /* Good to go. */ + grub_loader_set (grub_mb2_boot, grub_mb2_unload, 1); + return; + +fail: + grub_mb2_tags_free (); + grub_dl_unref (my_mod); +} + +void +grub_module2 (int argc, char *argv[]) +{ + grub_file_t file; + grub_addr_t modaddr = 0; + grub_ssize_t modsize = 0; + grub_err_t err; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + return; + } + + if (argc == 1) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified"); + return; + } + + if (entry == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "You need to load the multiboot kernel first"); + return; + } + + /* Load module data. */ + file = grub_gzfile_open (argv[0], 1); + if (! file) + goto out; + + modsize = grub_file_size (file); + err = grub_mb2_arch_module_alloc (modsize, &modaddr); + if (err) + goto out; + + grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr, + modaddr + modsize); + if (grub_file_read (file, (char *) modaddr, modsize) != modsize) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto out; + } + + /* Create the module tag. */ + err = grub_mb2_tag_module_create (modaddr, modsize, + argv[1], MULTIBOOT2_TAG_MODULE, + argc-2, &argv[2]); + if (err) + goto out; + +out: + grub_error_push (); + + if (file) + grub_file_close (file); + + if (modaddr) + grub_mb2_arch_module_free (modaddr, modsize); + + grub_error_pop (); +} diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c new file mode 100644 index 0000000..abcad9b --- /dev/null +++ b/loader/multiboot_loader.c @@ -0,0 +1,203 @@ +/* multiboot_loader.c - boot multiboot 1 or 2 OS image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +grub_dl_t my_mod; + +/* This tracks which version of multiboot to use when using + * the module command. By default use multiboot version 1. + * values: + * 1 - Multiboot version 1 + * 2 - Multiboot version 2 + */ + +static unsigned int module_version_status = 1; + +static int +find_multi_boot1_header (grub_file_t file) +{ + struct grub_multiboot_header *header; + char buffer[MULTIBOOT_SEARCH]; + int found_status = 0; + grub_ssize_t len; + + len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); + if (len < 32) + return found_status; + + /* Look for the multiboot header in the buffer. The header should + be at least 12 bytes and aligned on a 4-byte boundary. */ + for (header = (struct grub_multiboot_header *) buffer; + ((char *) header <= buffer + len - 12) || (header = 0); + header = (struct grub_multiboot_header *) ((char *) header + 4)) + { + if (header->magic == MULTIBOOT_MAGIC + && !(header->magic + header->flags + header->checksum)) + { + found_status = 1; + break; + } + } + + return found_status; +} + +static int +find_multi_boot2_header (grub_file_t file) +{ + struct multiboot_header *header; + char buffer[MULTIBOOT_SEARCH]; + int found_status = 0; + grub_ssize_t len; + + len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); + if (len < 32) + return found_status; + + /* Look for the multiboot header in the buffer. The header should + be at least 8 bytes and aligned on a 8-byte boundary. */ + for (header = (struct multiboot_header *) buffer; + ((char *) header <= buffer + len - 8) || (header = 0); + header = (struct multiboot_header *) ((char *) header + 8)) + { + if (header->magic == MULTIBOOT2_HEADER_MAGIC) + { + found_status = 1; + break; + } + } + + return found_status; +} + +void +grub_rescue_cmd_multiboot_loader (int argc, char *argv[]) +{ + + grub_file_t file = 0; + int header_multi_ver_found = 0; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + goto fail; + } + + file = grub_gzfile_open (argv[0], 1); + if (! file) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + goto fail; + } + + /* find which header is in the file */ + if (find_multi_boot1_header (file)) + header_multi_ver_found = 1; + else if (find_multi_boot2_header (file)) + header_multi_ver_found = 2; + else + { + grub_error (GRUB_ERR_BAD_OS, "Multiboot header not found"); + goto fail; + } + + /* close file before calling functions */ + if (file) + grub_file_close (file); + + /* Launch multi boot with header */ + + /* XXX Find a better way to identify this. + This is for i386-pc */ +#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) + if (header_multi_ver_found == 1) + { + grub_dprintf ("multiboot_loader", + "Launching multiboot 1 grub_multiboot() function\n"); + grub_multiboot (argc, argv); + module_version_status = 1; + } +#endif + if (header_multi_ver_found == 0 || header_multi_ver_found == 2) + { + grub_dprintf ("multiboot_loader", + "Launching multiboot 2 grub_multiboot2() function\n"); + grub_multiboot2 (argc, argv); + module_version_status = 2; + } + + return; + +fail: + if (file) + grub_file_close (file); + + grub_dl_unref (my_mod); +} + +void +grub_rescue_cmd_module_loader (int argc, char *argv[]) +{ + +#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) + if (module_version_status == 1) + { + grub_dprintf("multiboot_loader", + "Launching multiboot 1 grub_module() function\n"); + grub_module (argc, argv); + } +#endif + if (module_version_status == 2) + { + grub_dprintf("multiboot_loader", + "Launching multiboot 2 grub_module2() function\n"); + grub_module2 (argc, argv); + } +} + +GRUB_MOD_INIT(multiboot) +{ + grub_rescue_register_command ("multiboot", grub_rescue_cmd_multiboot_loader, + "load a multiboot kernel"); + grub_rescue_register_command ("module", grub_rescue_cmd_module_loader, + "load a multiboot module"); + + my_mod = mod; +} + +GRUB_MOD_FINI(multiboot) +{ + grub_rescue_unregister_command ("multiboot"); + grub_rescue_unregister_command ("module"); +} diff --git a/loader/multiboot_loader_normal.c b/loader/multiboot_loader_normal.c new file mode 100644 index 0000000..4a1a029 --- /dev/null +++ b/loader/multiboot_loader_normal.c @@ -0,0 +1,61 @@ +/* multiboot_loader_normal.c - boot another boot loader */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_normal_cmd_multiboot (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_multiboot_loader (argc, args); + return grub_errno; +} + +static grub_err_t +grub_normal_cmd_module (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_module_loader (argc, args); + return grub_errno; +} + +GRUB_MOD_INIT(multiboot_loader_normal) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("multiboot", grub_normal_cmd_multiboot, + GRUB_COMMAND_FLAG_BOTH + | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "multiboot FILE [ARGS...]", + "Load a Multiboot kernel.", 0); + + grub_register_command ("module", grub_normal_cmd_module, + GRUB_COMMAND_FLAG_BOTH + | GRUB_COMMAND_FLAG_NO_ARG_PARSE, + "module FILE [ARGS...]", + "Load a Multiboot module.", 0); +} + +GRUB_MOD_FINI(multiboot_loader_normal) +{ + grub_unregister_command ("multiboot"); + grub_unregister_command ("module"); +} diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c new file mode 100644 index 0000000..3b85341 --- /dev/null +++ b/loader/powerpc/ieee1275/linux.c @@ -0,0 +1,343 @@ +/* linux.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ELF32_LOADMASK (0xc0000000UL) +#define ELF64_LOADMASK (0xc000000000000000ULL) + +static grub_dl_t my_mod; + +static int loaded; + +static grub_addr_t initrd_addr; +static grub_size_t initrd_size; + +static grub_addr_t linux_addr; +static grub_size_t linux_size; + +static char *linux_args; + +typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), + unsigned long, unsigned long); + +static grub_err_t +grub_linux_boot (void) +{ + kernel_entry_t linuxmain; + grub_ssize_t actual; + + /* Set the command line arguments. */ + grub_ieee1275_set_property (grub_ieee1275_chosen, "bootargs", linux_args, + grub_strlen (linux_args) + 1, &actual); + + grub_dprintf ("loader", "Entry point: 0x%x\n", linux_addr); + grub_dprintf ("loader", "Initrd at: 0x%x, size 0x%x\n", initrd_addr, + initrd_size); + grub_dprintf ("loader", "Boot arguments: %s\n", linux_args); + grub_dprintf ("loader", "Jumping to Linux...\n"); + + /* Boot the kernel. */ + linuxmain = (kernel_entry_t) linux_addr; + linuxmain ((void *) initrd_addr, initrd_size, grub_ieee1275_entry_fn, 0, 0); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_release_mem (void) +{ + grub_free (linux_args); + linux_args = 0; + + if (linux_addr && grub_ieee1275_release (linux_addr, linux_size)) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory"); + + if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size)) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory"); + + linux_addr = 0; + initrd_addr = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_err_t err; + + err = grub_linux_release_mem (); + grub_dl_unref (my_mod); + + loaded = 0; + + return err; +} + +static grub_err_t +grub_linux_load32 (grub_elf_t elf) +{ + Elf32_Addr entry; + int found_addr = 0; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; + if (entry == 0) + entry = 0x01400000; + + linux_size = grub_elf32_size (elf); + if (linux_size == 0) + return grub_errno; + /* Pad it; the kernel scribbles over memory beyond its load address. */ + linux_size += 0x100000; + + /* On some systems, firmware occupies the memory we're trying to use. + * Happily, Linux can be loaded anywhere (it relocates itself). Iterate + * until we find an open area. */ + for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) + { + grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", + linux_addr, linux_size); + found_addr = grub_claimmap (linux_addr, linux_size); + if (found_addr != -1) + break; + } + if (found_addr == -1) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory."); + + /* Now load the segments into the area we claimed. */ + auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr); + grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr) + { + /* Linux's program headers incorrectly contain virtual addresses. + * Translate those to physical, and offset to the area we claimed. */ + *addr = (phdr->p_paddr & ~ELF32_LOADMASK) + linux_addr; + return 0; + } + return grub_elf32_load (elf, offset_phdr, 0, 0); +} + +static grub_err_t +grub_linux_load64 (grub_elf_t elf) +{ + Elf64_Addr entry; + int found_addr = 0; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; + if (entry == 0) + entry = 0x01400000; + + linux_size = grub_elf64_size (elf); + if (linux_size == 0) + return grub_errno; + /* Pad it; the kernel scribbles over memory beyond its load address. */ + linux_size += 0x100000; + + /* On some systems, firmware occupies the memory we're trying to use. + * Happily, Linux can be loaded anywhere (it relocates itself). Iterate + * until we find an open area. */ + for (linux_addr = entry; linux_addr < entry + 200 * 0x100000; linux_addr += 0x100000) + { + grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", + linux_addr, linux_size); + found_addr = grub_claimmap (linux_addr, linux_size); + if (found_addr != -1) + break; + } + if (found_addr == -1) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory."); + + /* Now load the segments into the area we claimed. */ + auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr); + grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr) + { + /* Linux's program headers incorrectly contain virtual addresses. + * Translate those to physical, and offset to the area we claimed. */ + *addr = (phdr->p_paddr & ~ELF64_LOADMASK) + linux_addr; + return 0; + } + return grub_elf64_load (elf, offset_phdr, 0, 0); +} + +void +grub_rescue_cmd_linux (int argc, char *argv[]) +{ + grub_elf_t elf = 0; + int i; + int size; + char *dest; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto out; + } + + elf = grub_elf_open (argv[0]); + if (! elf) + goto out; + + if (elf->ehdr.ehdr32.e_type != ET_EXEC) + { + grub_error (GRUB_ERR_UNKNOWN_OS, + "This ELF file is not of the right type\n"); + goto out; + } + + /* Release the previously used memory. */ + grub_loader_unset (); + + if (grub_elf_is_elf32 (elf)) + grub_linux_load32 (elf); + else + if (grub_elf_is_elf64 (elf)) + grub_linux_load64 (elf); + else + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); + goto out; + } + + size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); + for (i = 0; i < argc; i++) + size += grub_strlen (argv[i]) + 1; + + linux_args = grub_malloc (size); + if (! linux_args) + goto out; + + /* Specify the boot file. */ + dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); + dest = grub_stpcpy (dest, argv[0]); + + for (i = 1; i < argc; i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + +out: + + if (elf) + grub_elf_close (elf); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_linux_release_mem (); + grub_dl_unref (my_mod); + loaded = 0; + } + else + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + initrd_addr = 0; + loaded = 1; + } +} + +void +grub_rescue_cmd_initrd (int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_addr_t first_addr; + grub_addr_t addr; + int found_addr = 0; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + goto fail; + + first_addr = linux_addr + linux_size; + size = grub_file_size (file); + + /* Attempt to claim at a series of addresses until successful in + the same way that grub_rescue_cmd_linux does. */ + for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000) + { + grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n", + addr, size); + found_addr = grub_claimmap (addr, size); + if (found_addr != -1) + break; + } + + if (found_addr == -1) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory"); + goto fail; + } + + grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); + + if (grub_file_read (file, (void *) addr, size) != size) + { + grub_ieee1275_release (addr, size); + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + goto fail; + } + + initrd_addr = addr; + initrd_size = size; + + fail: + if (file) + grub_file_close (file); +} + + + +GRUB_MOD_INIT(linux) +{ + grub_rescue_register_command ("linux", grub_rescue_cmd_linux, + "load a linux kernel"); + grub_rescue_register_command ("initrd", grub_rescue_cmd_initrd, + "load an initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_rescue_unregister_command ("linux"); + grub_rescue_unregister_command ("initrd"); +} diff --git a/loader/powerpc/ieee1275/linux_normal.c b/loader/powerpc/ieee1275/linux_normal.c new file mode 100644 index 0000000..619eb33 --- /dev/null +++ b/loader/powerpc/ieee1275/linux_normal.c @@ -0,0 +1,60 @@ +/* linux_normal.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {0, 0, 0, 0, 0, 0} + }; + +static grub_err_t +grub_cmd_linux (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_linux (argc, args); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_initrd (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_rescue_cmd_initrd (argc, args); + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(linux_normal) +{ + (void) mod; + grub_register_command ("linux", grub_cmd_linux, GRUB_COMMAND_FLAG_BOTH, + "linux [KERNELARGS...]", + "Loads linux", options); + grub_register_command ("initrd", grub_cmd_initrd, GRUB_COMMAND_FLAG_BOTH, + "initrd FILE", + "Loads initrd", options); +} + +GRUB_MOD_FINI(linux_normal) +{ + grub_unregister_command ("linux"); + grub_unregister_command ("initrd"); +} diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..ef7e16f --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,161 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2006-05-11.19 + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/normal/arg.c b/normal/arg.c new file mode 100644 index 0000000..52c11d3 --- /dev/null +++ b/normal/arg.c @@ -0,0 +1,419 @@ +/* arg.c - argument parser */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Built-in parser for default options. */ +#define SHORT_ARG_HELP -100 +#define SHORT_ARG_USAGE -101 + +static const struct grub_arg_option help_options[] = + { + {"help", SHORT_ARG_HELP, 0, + "display this help and exit", 0, ARG_TYPE_NONE}, + {"usage", SHORT_ARG_USAGE, 0, + "display the usage of this command and exit", 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} + }; + +static struct grub_arg_option * +find_short (const struct grub_arg_option *options, char c) +{ + struct grub_arg_option *found = 0; + auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt); + + struct grub_arg_option *fnd_short (const struct grub_arg_option *opt) + { + while (opt->doc) + { + if (opt->shortarg == c) + return (struct grub_arg_option *) opt; + opt++; + } + return 0; + } + + if (options) + found = fnd_short (options); + + if (! found) + { + switch (c) + { + case 'h': + found = (struct grub_arg_option *) help_options; + break; + + case 'u': + found = (struct grub_arg_option *) (help_options + 1); + break; + + default: + break; + } + } + + return found; +} + +static char * +find_long_option (char *s) +{ + char *argpos = grub_strchr (s, '='); + + if (argpos) + { + *argpos = '\0'; + return ++argpos; + } + return 0; +} + +static struct grub_arg_option * +find_long (const struct grub_arg_option *options, char *s) +{ + struct grub_arg_option *found = 0; + auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt); + + struct grub_arg_option *fnd_long (const struct grub_arg_option *opt) + { + while (opt->doc) + { + if (opt->longarg && ! grub_strcmp (opt->longarg, s)) + return (struct grub_arg_option *) opt; + opt++; + } + return 0; + } + + if (options) + found = fnd_long (options); + + if (! found) + found = fnd_long (help_options); + + return found; +} + +static void +show_usage (grub_command_t cmd) +{ + grub_printf ("Usage: %s\n", cmd->summary); +} + +void +grub_arg_show_help (grub_command_t cmd) +{ + auto void showargs (const struct grub_arg_option *opt); + int h_is_used = 0; + int u_is_used = 0; + + auto void showargs (const struct grub_arg_option *opt) + { + for (; opt->doc; opt++) + { + int spacing = 20; + + if (opt->shortarg && grub_isgraph (opt->shortarg)) + grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' '); + else if (opt->shortarg == SHORT_ARG_HELP && ! h_is_used) + grub_printf ("-h, "); + else if (opt->shortarg == SHORT_ARG_USAGE && ! u_is_used) + grub_printf ("-u, "); + else + grub_printf (" "); + + if (opt->longarg) + { + grub_printf ("--%s", opt->longarg); + spacing -= grub_strlen (opt->longarg) + 2; + + if (opt->arg) + { + grub_printf ("=%s", opt->arg); + spacing -= grub_strlen (opt->arg) + 1; + } + } + + const char *doc = opt->doc; + for (;;) + { + while (spacing-- > 0) + grub_putchar (' '); + + while (*doc && *doc != '\n') + grub_putchar (*doc++); + grub_putchar ('\n'); + + if (! *doc) + break; + doc++; + spacing = 4 + 20; + } + + switch (opt->shortarg) + { + case 'h': + h_is_used = 1; + break; + + case 'u': + u_is_used = 1; + break; + + default: + break; + } + } + } + + show_usage (cmd); + grub_printf ("%s\n\n", cmd->description); + if (cmd->options) + showargs (cmd->options); + showargs (help_options); +#if 0 + grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); +#endif +} + + +static int +parse_option (grub_command_t cmd, int key, char *arg, struct grub_arg_list *usr) +{ + switch (key) + { + case SHORT_ARG_HELP: + grub_arg_show_help (cmd); + return -1; + + case SHORT_ARG_USAGE: + show_usage (cmd); + return -1; + + default: + { + int found = -1; + int i = 0; + const struct grub_arg_option *opt = cmd->options; + + while (opt->doc) + { + if (opt->shortarg && key == opt->shortarg) + { + found = i; + break; + } + opt++; + i++; + } + + if (found == -1) + return -1; + + usr[found].set = 1; + usr[found].arg = arg; + } + } + + return 0; +} + +int +grub_arg_parse (grub_command_t cmd, int argc, char **argv, + struct grub_arg_list *usr, char ***args, int *argnum) +{ + int curarg; + char *longarg = 0; + int complete = 0; + char **argl = 0; + int num = 0; + auto grub_err_t add_arg (char *s); + + grub_err_t add_arg (char *s) + { + argl = grub_realloc (argl, (++num) * sizeof (char *)); + if (! argl) + return grub_errno; + argl[num - 1] = s; + return 0; + } + + + for (curarg = 0; curarg < argc; curarg++) + { + char *arg = argv[curarg]; + struct grub_arg_option *opt; + char *option = 0; + + /* No option is used. */ + if (arg[0] != '-' || grub_strlen (arg) == 1) + { + if (add_arg (arg) != 0) + goto fail; + + continue; + } + + /* One or more short options. */ + if (arg[1] != '-') + { + char *curshort = arg + 1; + + while (1) + { + opt = find_short (cmd->options, *curshort); + if (! opt) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unknown argument `-%c'\n", *curshort); + goto fail; + } + + curshort++; + + /* Parse all arguments here except the last one because + it can have an argument value. */ + if (*curshort) + { + if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno) + goto fail; + } + else + { + if (opt->type != ARG_TYPE_NONE) + { + if (curarg + 1 < argc) + { + char *nextarg = argv[curarg + 1]; + if (!(opt->flags & GRUB_ARG_OPTION_OPTIONAL) + || (grub_strlen (nextarg) < 2 || nextarg[0] != '-')) + option = argv[++curarg]; + } + } + break; + } + } + + } + else /* The argument starts with "--". */ + { + /* If the argument "--" is used just pass the other + arguments. */ + if (grub_strlen (arg) == 2) + { + for (curarg++; curarg < argc; curarg++) + if (add_arg (argv[curarg]) != 0) + goto fail; + break; + } + + longarg = (char *) grub_strdup (arg); + if (! longarg) + goto fail; + + option = find_long_option (longarg); + arg = longarg; + + opt = find_long (cmd->options, arg + 2); + if (! opt) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown argument `%s'\n", arg); + goto fail; + } + } + + if (! (opt->type == ARG_TYPE_NONE + || (! option && (opt->flags & GRUB_ARG_OPTION_OPTIONAL)))) + { + if (! option) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "Missing mandatory option for `%s'\n", opt->longarg); + goto fail; + } + + switch (opt->type) + { + case ARG_TYPE_NONE: + /* This will never happen. */ + break; + + case ARG_TYPE_STRING: + /* No need to do anything. */ + break; + + case ARG_TYPE_INT: + { + char *tail; + + grub_strtoul (option, &tail, 0); + if (tail == 0 || tail == option || *tail != '\0' || grub_errno) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "The argument `%s' requires an integer.", + arg); + + goto fail; + } + break; + } + + case ARG_TYPE_DEVICE: + case ARG_TYPE_DIR: + case ARG_TYPE_FILE: + case ARG_TYPE_PATHNAME: + /* XXX: Not implemented. */ + break; + } + if (parse_option (cmd, opt->shortarg, option, usr) || grub_errno) + goto fail; + } + else + { + if (option) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + "A value was assigned to the argument `%s' while it " + "doesn't require an argument\n", arg); + goto fail; + } + + if (parse_option (cmd, opt->shortarg, 0, usr) || grub_errno) + goto fail; + } + grub_free (longarg); + longarg = 0; + } + + complete = 1; + + *args = argl; + *argnum = num; + + fail: + grub_free (longarg); + + return complete; +} diff --git a/normal/cmdline.c b/normal/cmdline.c new file mode 100644 index 0000000..8ca83f6 --- /dev/null +++ b/normal/cmdline.c @@ -0,0 +1,512 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *kill_buf; + +static int hist_size; +static char **hist_lines = 0; +static int hist_pos = 0; +static int hist_end = 0; +static int hist_used = 0; + +grub_err_t +grub_set_history (int newsize) +{ + char **old_hist_lines = hist_lines; + hist_lines = grub_malloc (sizeof (char *) * newsize); + + /* Copy the old lines into the new buffer. */ + if (old_hist_lines) + { + /* Remove the lines that don't fit in the new buffer. */ + if (newsize < hist_used) + { + int i; + int delsize = hist_used - newsize; + hist_used = newsize; + + for (i = 1; i <= delsize; i++) + { + int pos = hist_end - i; + if (pos < 0) + pos += hist_size; + grub_free (old_hist_lines[pos]); + } + + hist_end -= delsize; + if (hist_end < 0) + hist_end += hist_size; + } + + if (hist_pos < hist_end) + grub_memmove (hist_lines, old_hist_lines + hist_pos, + (hist_end - hist_pos) * sizeof (char *)); + else if (hist_used) + { + /* Copy the older part. */ + grub_memmove (hist_lines, old_hist_lines + hist_pos, + (hist_size - hist_pos) * sizeof (char *)); + + /* Copy the newer part. */ + grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines, + hist_end * sizeof (char *)); + } + } + + grub_free (old_hist_lines); + + hist_size = newsize; + hist_pos = 0; + hist_end = hist_used; + return 0; +} + +/* Get the entry POS from the history where `0' is the newest + entry. */ +static char * +grub_history_get (int pos) +{ + pos = (hist_pos + pos) % hist_size; + return hist_lines[pos]; +} + + +/* Insert a new history line S on the top of the history. */ +static void +grub_history_add (char *s) +{ + /* Remove the oldest entry in the history to make room for a new + entry. */ + if (hist_used + 1 > hist_size) + { + hist_end--; + if (hist_end < 0) + hist_end = hist_size + hist_end; + + grub_free (hist_lines[hist_end]); + } + else + hist_used++; + + /* Move to the next position. */ + hist_pos--; + if (hist_pos < 0) + hist_pos = hist_size + hist_pos; + + /* Insert into history. */ + hist_lines[hist_pos] = grub_strdup (s); +} + +/* Replace the history entry on position POS with the string S. */ +static void +grub_history_replace (int pos, char *s) +{ + pos = (hist_pos + pos) % hist_size; + grub_free (hist_lines[pos]); + hist_lines[pos] = grub_strdup (s); +} + +void +grub_cmdline_run (int nested) +{ + grub_normal_init_page (); + grub_setcursor (1); + + grub_printf ("\ + [ Minimal BASH-like line editing is supported. For the first word, TAB\n\ + lists possible command completions. Anywhere else TAB lists possible\n\ + device/file completions.%s ]\n\n", + nested ? " ESC at any time exits." : ""); + + while (1) + { + static char cmdline[GRUB_MAX_CMDLINE]; + + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + cmdline[0] = '\0'; + + if (! grub_cmdline_get ("grub> ", cmdline, sizeof (cmdline), 0, 1) + && nested) + return; + + if (! *cmdline) + continue; + + grub_command_execute (cmdline, 1); + } +} + +/* A completion hook to print items. */ +static void +print_completion (const char *item, grub_completion_type_t type, int count) +{ + if (count == 0) + { + /* If this is the first time, print a label. */ + const char *what; + + switch (type) + { + case GRUB_COMPLETION_TYPE_COMMAND: + what = "commands"; + break; + case GRUB_COMPLETION_TYPE_DEVICE: + what = "devices"; + break; + case GRUB_COMPLETION_TYPE_FILE: + what = "files"; + break; + case GRUB_COMPLETION_TYPE_PARTITION: + what = "partitions"; + break; + case GRUB_COMPLETION_TYPE_ARGUMENT: + what = "arguments"; + break; + default: + what = "things"; + break; + } + + grub_printf ("\nPossible %s are:\n", what); + } + + if (type == GRUB_COMPLETION_TYPE_PARTITION) + { + grub_normal_print_device_info (item); + grub_errno = GRUB_ERR_NONE; + } + else + grub_printf (" %s", item); +} + +/* Get a command-line. If ECHO_CHAR is not zero, echo it instead of input + characters. If READLINE is non-zero, readline-like key bindings are + available. If ESC is pushed, return zero, otherwise return non-zero. */ +/* FIXME: The dumb interface is not supported yet. */ +int +grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, + int echo_char, int readline) +{ + unsigned xpos, ypos, ystart; + grub_size_t lpos, llen; + grub_size_t plen; + char buf[max_len]; + int key; + int histpos = 0; + auto void cl_insert (const char *str); + auto void cl_delete (unsigned len); + auto void cl_print (int pos, int c); + auto void cl_set_pos (void); + + void cl_set_pos (void) + { + xpos = (plen + lpos) % 79; + ypos = ystart + (plen + lpos) / 79; + grub_gotoxy (xpos, ypos); + + grub_refresh (); + } + + void cl_print (int pos, int c) + { + char *p; + + for (p = buf + pos; *p; p++) + { + if (xpos++ > 78) + { + grub_putchar ('\n'); + + xpos = 1; + if (ypos == (unsigned) (grub_getxy () & 0xFF)) + ystart--; + else + ypos++; + } + + if (c) + grub_putchar (c); + else + grub_putchar (*p); + } + } + + void cl_insert (const char *str) + { + grub_size_t len = grub_strlen (str); + + if (len + llen < max_len) + { + grub_memmove (buf + lpos + len, buf + lpos, llen - lpos + 1); + grub_memmove (buf + lpos, str, len); + + llen += len; + lpos += len; + cl_print (lpos - len, echo_char); + cl_set_pos (); + } + + grub_refresh (); + } + + void cl_delete (unsigned len) + { + if (lpos + len <= llen) + { + grub_size_t saved_lpos = lpos; + + lpos = llen - len; + cl_set_pos (); + cl_print (lpos, ' '); + lpos = saved_lpos; + cl_set_pos (); + + grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1); + llen -= len; + cl_print (lpos, echo_char); + cl_set_pos (); + } + + grub_refresh (); + } + + plen = grub_strlen (prompt); + lpos = llen = 0; + buf[0] = '\0'; + + if ((grub_getxy () >> 8) != 0) + grub_putchar ('\n'); + + grub_printf (prompt); + + xpos = plen; + ystart = ypos = (grub_getxy () & 0xFF); + + cl_insert (cmdline); + + if (hist_used == 0) + grub_history_add (buf); + + while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') + { + if (readline) + { + switch (key) + { + case 1: /* Ctrl-a */ + lpos = 0; + cl_set_pos (); + break; + + case 2: /* Ctrl-b */ + if (lpos > 0) + { + lpos--; + cl_set_pos (); + } + break; + + case 5: /* Ctrl-e */ + lpos = llen; + cl_set_pos (); + break; + + case 6: /* Ctrl-f */ + if (lpos < llen) + { + lpos++; + cl_set_pos (); + } + break; + + case 9: /* Ctrl-i or TAB */ + { + char *insert; + int restore; + + /* Backup the next character and make it 0 so it will + be easy to use string functions. */ + char backup = buf[lpos]; + buf[lpos] = '\0'; + + + insert = grub_normal_do_completion (buf, &restore, + print_completion); + /* Restore the original string. */ + buf[lpos] = backup; + + if (restore) + { + /* Restore the prompt. */ + grub_printf ("\n%s%s", prompt, buf); + xpos = plen; + ystart = ypos = (grub_getxy () & 0xFF); + } + + if (insert) + { + cl_insert (insert); + grub_free (insert); + } + } + break; + + case 11: /* Ctrl-k */ + if (lpos < llen) + { + if (kill_buf) + grub_free (kill_buf); + + kill_buf = grub_strdup (buf + lpos); + grub_errno = GRUB_ERR_NONE; + + cl_delete (llen - lpos); + } + break; + + case 14: /* Ctrl-n */ + { + char *hist; + + lpos = 0; + + if (histpos > 0) + { + grub_history_replace (histpos, buf); + histpos--; + } + + cl_delete (llen); + hist = grub_history_get (histpos); + cl_insert (hist); + + break; + } + case 16: /* Ctrl-p */ + { + char *hist; + + lpos = 0; + + if (histpos < hist_used - 1) + { + grub_history_replace (histpos, buf); + histpos++; + } + + cl_delete (llen); + hist = grub_history_get (histpos); + + cl_insert (hist); + } + break; + + case 21: /* Ctrl-u */ + if (lpos > 0) + { + grub_size_t n = lpos; + + if (kill_buf) + grub_free (kill_buf); + + kill_buf = grub_malloc (n + 1); + grub_errno = GRUB_ERR_NONE; + if (kill_buf) + { + grub_memcpy (kill_buf, buf, n); + kill_buf[n] = '\0'; + } + + lpos = 0; + cl_set_pos (); + cl_delete (n); + } + break; + + case 25: /* Ctrl-y */ + if (kill_buf) + cl_insert (kill_buf); + break; + } + } + + switch (key) + { + case '\e': + return 0; + + case '\b': + if (lpos > 0) + { + lpos--; + cl_set_pos (); + } + else + break; + /* fall through */ + + case 4: /* Ctrl-d */ + if (lpos < llen) + cl_delete (1); + break; + + default: + if (grub_isprint (key)) + { + char str[2]; + + str[0] = key; + str[1] = '\0'; + cl_insert (str); + } + break; + } + } + + grub_putchar ('\n'); + grub_refresh (); + + /* If ECHO_CHAR is NUL, remove leading spaces. */ + lpos = 0; + if (! echo_char) + while (buf[lpos] == ' ') + lpos++; + + histpos = 0; + if (grub_strlen (buf) > 0) + { + grub_history_replace (histpos, buf); + grub_history_add (""); + } + + grub_memcpy (cmdline, buf + lpos, llen - lpos + 1); + + return 1; +} diff --git a/normal/color.c b/normal/color.c new file mode 100644 index 0000000..340e43a --- /dev/null +++ b/normal/color.c @@ -0,0 +1,148 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Borrowed from GRUB Legacy */ +static char *color_list[16] = +{ + "black", + "blue", + "green", + "cyan", + "red", + "magenta", + "brown", + "light-gray", + "dark-gray", + "light-blue", + "light-green", + "light-cyan", + "light-red", + "light-magenta", + "yellow", + "white" +}; + +static int +parse_color_name (grub_uint8_t *ret, char *name) +{ + grub_uint8_t i; + for (i = 0; i < sizeof (color_list) / sizeof (*color_list); i++) + if (! grub_strcmp (name, color_list[i])) + { + *ret = i; + return 0; + } + return -1; +} + +void +grub_parse_color_name_pair (grub_uint8_t *ret, const char *name) +{ + grub_uint8_t fg, bg; + char *fg_name, *bg_name; + + /* nothing specified by user */ + if (name == NULL) + return; + + fg_name = grub_strdup (name); + if (fg_name == NULL) + { + /* "out of memory" message was printed by grub_strdup() */ + grub_wait_after_message (); + return; + } + + bg_name = grub_strchr (fg_name, '/'); + if (bg_name == NULL) + { + grub_printf ("Warning: syntax error (missing slash) in `%s'\n", fg_name); + grub_wait_after_message (); + goto free_and_return; + } + + *(bg_name++) = '\0'; + + if (parse_color_name (&fg, fg_name) == -1) + { + grub_printf ("Warning: invalid foreground color `%s'\n", fg_name); + grub_wait_after_message (); + goto free_and_return; + } + if (parse_color_name (&bg, bg_name) == -1) + { + grub_printf ("Warning: invalid background color `%s'\n", bg_name); + grub_wait_after_message (); + goto free_and_return; + } + + *ret = (bg << 4) | fg; + +free_and_return: + grub_free (fg_name); +} + +/* Replace default `normal' colors with the ones specified by user (if any). */ +char * +grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + grub_uint8_t color_normal, color_highlight; + + /* Use old settings in case grub_parse_color_name_pair() has no effect. */ + grub_getcolor (&color_normal, &color_highlight); + + grub_parse_color_name_pair (&color_normal, val); + + /* Reloads terminal `normal' and `highlight' colors. */ + grub_setcolor (color_normal, color_highlight); + + /* Propagates `normal' color to terminal current color. */ + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + + return grub_strdup (val); +} + +/* Replace default `highlight' colors with the ones specified by user (if any). */ +char * +grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + grub_uint8_t color_normal, color_highlight; + + /* Use old settings in case grub_parse_color_name_pair() has no effect. */ + grub_getcolor (&color_normal, &color_highlight); + + grub_parse_color_name_pair (&color_highlight, val); + + /* Reloads terminal `normal' and `highlight' colors. */ + grub_setcolor (color_normal, color_highlight); + + /* Propagates `normal' color to terminal current color. + Note: Using GRUB_TERM_COLOR_NORMAL here rather than + GRUB_TERM_COLOR_HIGHLIGHT is intentional. We don't want to switch + to highlight state just because color was reloaded. */ + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + + return grub_strdup (val); +} diff --git a/normal/command.c b/normal/command.c new file mode 100644 index 0000000..6ca56da --- /dev/null +++ b/normal/command.c @@ -0,0 +1,394 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_command_t grub_command_list; + +grub_command_t +grub_register_command (const char *name, + grub_err_t (*func) (struct grub_arg_list *state, + int argc, char **args), + unsigned flags, + const char *summary, + const char *description, + const struct grub_arg_option *options) +{ + grub_command_t cmd, *p; + + cmd = (grub_command_t) grub_malloc (sizeof (*cmd)); + if (! cmd) + return 0; + + cmd->name = grub_strdup (name); + if (! cmd->name) + { + grub_free (cmd); + return 0; + } + + cmd->func = func; + cmd->flags = flags; + cmd->summary = summary; + cmd->description = description; + cmd->options = options; + cmd->module_name = 0; + + /* Keep the list sorted for simplicity. */ + p = &grub_command_list; + while (*p) + { + if (grub_strcmp ((*p)->name, name) >= 0) + break; + + p = &((*p)->next); + } + + if (*p && grub_strcmp ((*p)->name, name) == 0) + { + grub_command_t q; + + q = *p; + if (q->flags & GRUB_COMMAND_FLAG_NOT_LOADED) + { + q->func = cmd->func; + q->flags = cmd->flags; + q->summary = cmd->summary; + q->description = cmd->description; + q->options = cmd->options; + grub_free (cmd->name); + grub_free (cmd->module_name); + grub_free (cmd); + cmd = q; + } + else + { + grub_free (cmd->name); + grub_free (cmd); + cmd = 0; + } + } + else + { + cmd->next = *p; + *p = cmd; + } + + return cmd; +} + +void +grub_unregister_command (const char *name) +{ + grub_command_t *p, q; + + for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next) + if (grub_strcmp (name, q->name) == 0) + { + *p = q->next; + grub_free (q->name); + grub_free (q->module_name); + grub_free (q); + break; + } +} + +grub_command_t +grub_command_find (char *cmdline) +{ + char *first_space; + grub_command_t cmd; + int count = 0; + + first_space = grub_strchr (cmdline, ' '); + if (first_space) + *first_space = '\0'; + + again: + + for (cmd = grub_command_list; cmd; cmd = cmd->next) + if (grub_strcmp (cmdline, cmd->name) == 0) + break; + + if (! cmd) + grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline); + else if (cmd->flags & GRUB_COMMAND_FLAG_NOT_LOADED) + { + /* Automatically load the command. */ + if (count == 0) + { + grub_dl_t mod; + char *module_name; + + module_name = grub_strdup (cmd->module_name); + if (module_name) + { + mod = grub_dl_load (module_name); + if (mod) + { + grub_dl_ref (mod); + count++; + grub_free (module_name); + goto again; + } + + grub_free (module_name); + } + } + + /* This module seems broken. */ + grub_unregister_command (cmdline); + grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", cmdline); + cmd = 0; + } + + if (first_space) + *first_space = ' '; + + return cmd; +} + +int +grub_iterate_commands (int (*iterate) (grub_command_t)) +{ + grub_command_t cmd; + + for (cmd = grub_command_list; cmd; cmd = cmd->next) + if (iterate (cmd)) + return 1; + + return 0; +} + +int +grub_command_execute (char *cmdline, int interactive) +{ + auto grub_err_t cmdline_get (char **s); + grub_err_t cmdline_get (char **s) + { + *s = grub_malloc (GRUB_MAX_CMDLINE); + *s[0] = '\0'; + return grub_cmdline_get (">", *s, GRUB_MAX_CMDLINE, 0, 1); + } + + grub_err_t ret = 0; + char *pager; + struct grub_script *parsed_script; + + /* Enable the pager if the environment pager is set to 1. */ + if (interactive) + pager = grub_env_get ("pager"); + else + pager = NULL; + if (pager && (! grub_strcmp (pager, "1"))) + grub_set_more (1); + + /* Parse the script. */ + parsed_script = grub_script_parse (cmdline, cmdline_get); + + if (parsed_script) + { + /* Execute the command(s). */ + grub_script_execute (parsed_script); + + /* The parsed script was executed, throw it away. */ + grub_script_free (parsed_script); + } + + if (pager && (! grub_strcmp (pager, "1"))) + grub_set_more (0); + + return ret; +} + +static grub_err_t +rescue_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + grub_longjmp (grub_exit_env, 0); + + /* Never reach here. */ + return 0; +} + + +static grub_err_t +set_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + char *var; + char *val; + + auto int print_env (struct grub_env_var *env); + int print_env (struct grub_env_var *env) + { + grub_printf ("%s=%s\n", env->name, env->value); + return 0; + } + + if (! argc) + { + grub_env_iterate (print_env); + return 0; + } + + var = args[0]; + val = grub_strchr (var, '='); + if (! val) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment"); + return grub_errno; + } + + val[0] = 0; + grub_env_set (var, val + 1); + val[0] = '='; + return 0; +} + +static grub_err_t +unset_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no environment variable specified"); + + grub_env_unset (args[0]); + return 0; +} + +static grub_err_t +export_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no environment variable specified"); + + grub_env_export (args[0]); + return 0; +} + +static grub_err_t +insmod_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + char *p; + grub_dl_t mod; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + + p = grub_strchr (args[0], '/'); + if (! p) + mod = grub_dl_load (args[0]); + else + mod = grub_dl_load_file (args[0]); + + if (mod) + grub_dl_ref (mod); + + return 0; +} + +static grub_err_t +rmmod_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + grub_dl_t mod; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + + mod = grub_dl_get (args[0]); + if (! mod) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module"); + + if (! grub_dl_unref (mod)) + grub_dl_unload (mod); + + return 0; +} + +static grub_err_t +lsmod_command (struct grub_arg_list *state __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + auto int print_module (grub_dl_t mod); + + int print_module (grub_dl_t mod) + { + grub_dl_dep_t dep; + + grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); + for (dep = mod->dep; dep; dep = dep->next) + { + if (dep != mod->dep) + grub_putchar (','); + + grub_printf ("%s", dep->mod->name); + } + grub_putchar ('\n'); + grub_refresh (); + + return 0; + } + + grub_printf ("Name\tRef Count\tDependencies\n"); + grub_dl_iterate (print_module); + return 0; +} + +void +grub_command_init (void) +{ + grub_register_command ("rescue", rescue_command, GRUB_COMMAND_FLAG_BOTH, + "rescue", "Go back to the rescue mode.", 0); + + grub_register_command ("set", set_command, GRUB_COMMAND_FLAG_BOTH, + "set [ENVVAR=VALUE]", + "Set an environment variable.", 0); + + grub_register_command ("unset", unset_command, GRUB_COMMAND_FLAG_BOTH, + "unset ENVVAR", "Remove an environment variable.", 0); + + grub_register_command ("export", export_command, GRUB_COMMAND_FLAG_BOTH, + "export ENVVAR", "Export a variable.", 0); + + grub_register_command ("insmod", insmod_command, GRUB_COMMAND_FLAG_BOTH, + "insmod MODULE", + "Insert a module. The argument can be a file or a module name.", + 0); + + grub_register_command ("rmmod", rmmod_command, GRUB_COMMAND_FLAG_BOTH, + "rmmod MODULE", "Remove a module.", 0); + + grub_register_command ("lsmod", lsmod_command, GRUB_COMMAND_FLAG_BOTH, + "lsmod", "Show loaded modules.", 0); +} diff --git a/normal/completion.c b/normal/completion.c new file mode 100644 index 0000000..fb38f28 --- /dev/null +++ b/normal/completion.c @@ -0,0 +1,493 @@ +/* completion.c - complete a command, a disk, a partition or a file */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* The current word. */ +static char *current_word; + +/* The matched string. */ +static char *match; + +/* The count of candidates. */ +static int num_found; + +/* The string to be appended. */ +static const char *suffix; + +/* The callback function to print items. */ +static void (*print_func) (const char *, grub_completion_type_t, int); + +/* The state the command line is in. */ +static grub_parser_state_t cmdline_state; + + +/* Add a string to the list of possible completions. COMPLETION is the + string that should be added. EXTRA will be appended if COMPLETION + matches uniquely. The type TYPE specifies what kind of data is added. */ +static int +add_completion (const char *completion, const char *extra, + grub_completion_type_t type) +{ + if (grub_strncmp (current_word, completion, grub_strlen (current_word)) == 0) + { + num_found++; + + switch (num_found) + { + case 1: + match = grub_strdup (completion); + if (! match) + return 1; + suffix = extra; + break; + + case 2: + if (print_func) + print_func (match, type, 0); + + /* Fall through. */ + + default: + { + char *s = match; + const char *t = completion; + + if (print_func) + print_func (completion, type, num_found - 1); + + /* Detect the matched portion. */ + while (*s && *t && *s == *t) + { + s++; + t++; + } + + *s = '\0'; + } + break; + } + } + + return 0; +} + +static int +iterate_partition (grub_disk_t disk, const grub_partition_t p) +{ + const char *disk_name = disk->name; + char *partition_name = grub_partition_get_name (p); + char *name; + int ret; + + if (! partition_name) + return 1; + + name = grub_malloc (grub_strlen (disk_name) + 1 + + grub_strlen (partition_name) + 1); + if (! name) + { + grub_free (partition_name); + return 1; + } + + grub_sprintf (name, "%s,%s", disk_name, partition_name); + grub_free (partition_name); + + ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION); + grub_free (name); + return ret; +} + +static int +iterate_dir (const char *filename, int dir) +{ + if (! dir) + { + const char *prefix; + if (cmdline_state == GRUB_PARSER_STATE_DQUOTE) + prefix = "\" "; + else if (cmdline_state == GRUB_PARSER_STATE_QUOTE) + prefix = "\' "; + else + prefix = " "; + + if (add_completion (filename, prefix, GRUB_COMPLETION_TYPE_FILE)) + return 1; + } + else if (grub_strcmp (filename, ".") && grub_strcmp (filename, "..")) + { + char fname[grub_strlen (filename) + 2]; + + grub_sprintf (fname, "%s/", filename); + if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE)) + return 1; + } + + return 0; +} + +static int +iterate_dev (const char *devname) +{ + grub_device_t dev; + + /* Complete the partition part. */ + dev = grub_device_open (devname); + + if (dev) + { + if (dev->disk && dev->disk->has_partitions) + { + if (add_completion (devname, ",", GRUB_COMPLETION_TYPE_DEVICE)) + return 1; + } + else + { + if (add_completion (devname, ")", GRUB_COMPLETION_TYPE_DEVICE)) + return 1; + } + } + + grub_errno = GRUB_ERR_NONE; + return 0; +} + +static int +iterate_command (grub_command_t cmd) +{ + if (grub_command_find (cmd->name)) + { + if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) + { + if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) + return 1; + } + } + + return 0; +} + +/* Complete a device. */ +static int +complete_device (void) +{ + /* Check if this is a device or a partition. */ + char *p = grub_strchr (++current_word, ','); + grub_device_t dev; + + if (! p) + { + /* Complete the disk part. */ + if (grub_disk_dev_iterate (iterate_dev)) + return 1; + } + else + { + /* Complete the partition part. */ + *p = '\0'; + dev = grub_device_open (current_word); + *p = ','; + grub_errno = GRUB_ERR_NONE; + + if (dev) + { + if (dev->disk && dev->disk->has_partitions) + { + if (grub_partition_iterate (dev->disk, iterate_partition)) + { + grub_device_close (dev); + return 1; + } + } + + grub_device_close (dev); + } + else + return 1; + } + + return 0; +} + +/* Complete a file. */ +static int +complete_file (void) +{ + char *device; + char *dir; + char *last_dir; + grub_fs_t fs; + grub_device_t dev; + int ret = 0; + + device = grub_file_get_device_name (current_word); + if (grub_errno != GRUB_ERR_NONE) + return 1; + + dev = grub_device_open (device); + if (! dev) + { + ret = 1; + goto fail; + } + + fs = grub_fs_probe (dev); + if (! fs) + { + ret = 1; + goto fail; + } + + dir = grub_strchr (current_word, '/'); + last_dir = grub_strrchr (current_word, '/'); + if (dir) + { + char *dirfile; + + current_word = last_dir + 1; + + dir = grub_strdup (dir); + if (! dir) + { + ret = 1; + goto fail; + } + + /* Cut away the filename part. */ + dirfile = grub_strrchr (dir, '/'); + dirfile[1] = '\0'; + + /* Iterate the directory. */ + (fs->dir) (dev, dir, iterate_dir); + + grub_free (dir); + + if (grub_errno) + { + ret = 1; + goto fail; + } + } + else + { + current_word += grub_strlen (current_word); + match = grub_strdup ("/"); + if (! match) + { + ret = 1; + goto fail; + } + + suffix = ""; + num_found = 1; + } + + fail: + if (dev) + grub_device_close (dev); + grub_free (device); + return ret; +} + +/* Complete an argument. */ +static int +complete_arguments (char *command) +{ + grub_command_t cmd; + const struct grub_arg_option *option; + char shortarg[] = "- "; + + cmd = grub_command_find (command); + + if (!cmd || !cmd->options) + return 0; + + if (add_completion ("-u", " ", GRUB_COMPLETION_TYPE_ARGUMENT)) + return 1; + + /* Add the short arguments. */ + for (option = cmd->options; option->doc; option++) + { + if (! option->shortarg) + continue; + + shortarg[1] = option->shortarg; + if (add_completion (shortarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT)) + return 1; + + } + + /* First add the built-in arguments. */ + if (add_completion ("--help", " ", GRUB_COMPLETION_TYPE_ARGUMENT)) + return 1; + if (add_completion ("--usage", " ", GRUB_COMPLETION_TYPE_ARGUMENT)) + return 1; + + /* Add the long arguments. */ + for (option = cmd->options; option->doc; option++) + { + char *longarg; + if (!option->longarg) + continue; + + longarg = grub_malloc (grub_strlen (option->longarg)); + grub_sprintf (longarg, "--%s", option->longarg); + + if (add_completion (longarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT)) + { + grub_free (longarg); + return 1; + } + grub_free (longarg); + } + + return 0; +} + + +static grub_parser_state_t +get_state (const char *cmdline) +{ + grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; + char use; + + while (*cmdline) + state = grub_parser_cmdline_state (state, *(cmdline++), &use); + return state; +} + + +/* Try to complete the string in BUF. Return the characters that + should be added to the string. This command outputs the possible + completions by calling HOOK, in that case set RESTORE to 1 so the + caller can restore the prompt. */ +char * +grub_normal_do_completion (char *buf, int *restore, + void (*hook) (const char *, grub_completion_type_t, int)) +{ + int argc; + char **argv; + + /* Initialize variables. */ + match = 0; + num_found = 0; + suffix = ""; + print_func = hook; + + *restore = 1; + + if (grub_parser_split_cmdline (buf, 0, &argc, &argv)) + return 0; + + current_word = argv[argc]; + + /* Determine the state the command line is in, depending on the + state, it can be determined how to complete. */ + cmdline_state = get_state (buf); + + if (argc == 0) + { + /* Complete a command. */ + if (grub_iterate_commands (iterate_command)) + goto fail; + } + else if (*current_word == '-') + { + if (complete_arguments (buf)) + goto fail; + } + else if (*current_word == '(' && ! grub_strchr (current_word, ')')) + { + /* Complete a device. */ + if (complete_device ()) + goto fail; + } + else + { + /* Complete a file. */ + if (complete_file ()) + goto fail; + } + + /* If more than one match is found those matches will be printed and + the prompt should be restored. */ + if (num_found > 1) + *restore = 1; + else + *restore = 0; + + /* Return the part that matches. */ + if (match) + { + char *ret; + char *escstr; + char *newstr; + int current_len; + int match_len; + int spaces = 0; + + current_len = grub_strlen (current_word); + match_len = grub_strlen (match); + + /* Count the number of spaces that have to be escaped. XXX: + More than just spaces have to be escaped. */ + for (escstr = match + current_len; *escstr; escstr++) + if (*escstr == ' ') + spaces++; + + ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + spaces + 1); + newstr = ret; + for (escstr = match + current_len; *escstr; escstr++) + { + if (*escstr == ' ' && cmdline_state != GRUB_PARSER_STATE_QUOTE + && cmdline_state != GRUB_PARSER_STATE_QUOTE) + *(newstr++) = '\\'; + *(newstr++) = *escstr; + } + *newstr = '\0'; + + if (num_found == 1) + grub_strcat (ret, suffix); + + if (*ret == '\0') + { + grub_free (ret); + goto fail; + } + + grub_free (argv[0]); + grub_free (match); + return ret; + } + + fail: + grub_free (argv[0]); + grub_free (match); + grub_errno = GRUB_ERR_NONE; + + return 0; +} diff --git a/normal/execute.c b/normal/execute.c new file mode 100644 index 0000000..35b7a4b --- /dev/null +++ b/normal/execute.c @@ -0,0 +1,275 @@ +/* execute.c -- Execute a GRUB script. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +grub_script_execute_cmd (struct grub_script_cmd *cmd) +{ + if (cmd == 0) + return 0; + + return cmd->exec (cmd); +} + +/* Parse ARG and return the textual representation. Add strings are + concatenated and all values of the variables are filled in. */ +static char * +grub_script_execute_argument_to_string (struct grub_script_arg *arg) +{ + int size = 0; + char *val; + char *chararg; + struct grub_script_arg *argi; + + /* First determine the size of the argument. */ + for (argi = arg; argi; argi = argi->next) + { + if (argi->type == 1) + { + val = grub_env_get (argi->str); + if (val) + size += grub_strlen (val); + } + else + size += grub_strlen (argi->str); + } + + /* Create the argument. */ + chararg = grub_malloc (size + 1); + if (! chararg) + return 0; + + *chararg = '\0'; + /* First determine the size of the argument. */ + for (argi = arg; argi; argi = argi->next) + { + if (argi->type == 1) + { + val = grub_env_get (argi->str); + if (val) + grub_strcat (chararg, val); + } + else + grub_strcat (chararg, argi->str); + } + + return chararg; +} + +/* Execute a single command line. */ +grub_err_t +grub_script_execute_cmdline (struct grub_script_cmd *cmd) +{ + struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd; + struct grub_script_arglist *arglist; + char **args = 0; + int i = 0; + grub_command_t grubcmd; + struct grub_arg_list *state; + struct grub_arg_option *parser; + int maxargs = 0; + char **parsed_arglist; + int numargs; + grub_err_t ret = 0; + int argcount = 0; + grub_script_function_t func = 0; + char errnobuf[6]; + + /* Lookup the command. */ + grubcmd = grub_command_find (cmdline->cmdname); + if (! grubcmd) + { + /* Ignore errors. */ + grub_errno = GRUB_ERR_NONE; + + /* It's not a GRUB command, try all functions. */ + func = grub_script_function_find (cmdline->cmdname); + if (! func) + { + /* As a last resort, try if it is an assignment. */ + char *assign = grub_strdup (cmdline->cmdname); + char *eq = grub_strchr (assign, '='); + + if (eq) + { + /* Create two strings and set the variable. */ + *eq = '\0'; + eq++; + grub_env_set (assign, eq); + + /* This was set because the command was not found. */ + grub_errno = GRUB_ERR_NONE; + } + grub_free (assign); + return 0; + } + } + + if (cmdline->arglist) + { + argcount = cmdline->arglist->argcount; + + /* Create argv from the arguments. */ + args = grub_malloc (sizeof (char *) * argcount); + for (arglist = cmdline->arglist; arglist; arglist = arglist->next) + { + char *str; + str = grub_script_execute_argument_to_string (arglist->arg); + args[i++] = str; + } + } + + /* Execute the GRUB command or function. */ + if (grubcmd) + { + /* Count the amount of options the command has. */ + parser = (struct grub_arg_option *) grubcmd->options; + while (parser && (parser++)->doc) + maxargs++; + + /* Set up the option state. */ + state = grub_malloc (sizeof (struct grub_arg_list) * maxargs); + grub_memset (state, 0, sizeof (struct grub_arg_list) * maxargs); + + /* Start the command. */ + if (! (grubcmd->flags & GRUB_COMMAND_FLAG_NO_ARG_PARSE)) + { + if (grub_arg_parse (grubcmd, argcount, args, state, &parsed_arglist, &numargs)) + ret = (grubcmd->func) (state, numargs, parsed_arglist); + } + else + ret = (grubcmd->func) (state, argcount, args); + + grub_free (state); + } + else + ret = grub_script_function_call (func, argcount, args); + + /* Free arguments. */ + for (i = 0; i < argcount; i++) + grub_free (args[i]); + grub_free (args); + + grub_sprintf (errnobuf, "%d", ret); + grub_env_set ("?", errnobuf); + + return ret; +} + +/* Execute a block of one or more commands. */ +grub_err_t +grub_script_execute_cmdblock (struct grub_script_cmd *cmd) +{ + struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd; + + /* Loop over every command and execute it. */ + for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next) + grub_script_execute_cmd (cmd); + + return 0; +} + +/* Execute an if statement. */ +grub_err_t +grub_script_execute_cmdif (struct grub_script_cmd *cmd) +{ + struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd; + char *result; + + /* Check if the commands results in a true or a false. The value is + read from the env variable `?'. */ + grub_script_execute_cmd (cmdif->exec_to_evaluate); + result = grub_env_get ("?"); + + /* Execute the `if' or the `else' part depending on the value of + `?'. */ + if (result && ! grub_strcmp (result, "0")) + return grub_script_execute_cmd (cmdif->exec_on_true); + else + return grub_script_execute_cmd (cmdif->exec_on_false); +} + +/* Execute the menu entry generate statement. */ +grub_err_t +grub_script_execute_menuentry (struct grub_script_cmd *cmd) +{ + struct grub_script_cmd_menuentry *cmd_menuentry; + struct grub_script_arglist *arglist; + struct grub_script *script; + char **args = 0; + int argcount = 0; + int i = 0; + + cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd; + + if (cmd_menuentry->arglist) + { + argcount = cmd_menuentry->arglist->argcount; + + /* Create argv from the arguments. */ + args = grub_malloc (sizeof (char *) * argcount); + + if (! args) + { + return grub_errno; + } + + for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next) + { + char *str; + str = grub_script_execute_argument_to_string (arglist->arg); + args[i++] = str; + } + } + + /* Parse the menu entry *again*. */ + script = grub_script_parse ((char *) cmd_menuentry->sourcecode, 0); + + /* Add new menu entry. */ + if (script) + { + grub_normal_menu_addentry (argcount, (const char **)args, + script, cmd_menuentry->sourcecode); + } + + /* Free arguments. */ + for (i = 0; i < argcount; i++) + grub_free (args[i]); + grub_free (args); + + return grub_errno; +} + + + +/* Execute any GRUB pre-parsed command or script. */ +grub_err_t +grub_script_execute (struct grub_script *script) +{ + if (script == 0) + return 0; + + return grub_script_execute_cmd (script->cmd); +} diff --git a/normal/function.c b/normal/function.c new file mode 100644 index 0000000..4c08d15 --- /dev/null +++ b/normal/function.c @@ -0,0 +1,125 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_script_function_t grub_script_function_list; + +grub_script_function_t +grub_script_function_create (char *functionname, struct grub_script *cmd) +{ + grub_script_function_t func; + grub_script_function_t *p; + + func = (grub_script_function_t) grub_malloc (sizeof (*func)); + if (! func) + return 0; + + func->name = grub_strdup (functionname); + if (! func->name) + { + grub_free (func); + return 0; + } + + func->func = cmd; + + /* Keep the list sorted for simplicity. */ + p = &grub_script_function_list; + while (*p) + { + if (grub_strcmp ((*p)->name, functionname) >= 0) + break; + + p = &((*p)->next); + } + + /* If the function already exists, overwrite the old function. */ + if (*p && grub_strcmp ((*p)->name, functionname) == 0) + { + grub_script_function_t q; + + q = *p; + grub_script_free (q->func); + q->func = cmd; + grub_free (func); + func = q; + } + else + { + func->next = *p; + *p = func; + } + + return func; +} + +void +grub_script_function_remove (const char *name) +{ + grub_script_function_t *p, q; + + for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next) + if (grub_strcmp (name, q->name) == 0) + { + *p = q->next; + grub_free (q->name); + grub_script_free (q->func); + grub_free (q); + break; + } +} + +grub_script_function_t +grub_script_function_find (char *functionname) +{ + grub_script_function_t func; + + for (func = grub_script_function_list; func; func = func->next) + if (grub_strcmp (functionname, func->name) == 0) + break; + + if (! func) + grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", functionname); + + return func; +} + +int +grub_script_function_iterate (int (*iterate) (grub_script_function_t)) +{ + grub_script_function_t func; + + for (func = grub_script_function_list; func; func = func->next) + if (iterate (func)) + return 1; + + return 0; +} + +int +grub_script_function_call (grub_script_function_t func, + int argc __attribute__((unused)), + char **args __attribute__((unused))) +{ + /* XXX: Arguments are not supported yet. */ + return grub_script_execute (func->func); +} diff --git a/normal/i386/setjmp.S b/normal/i386/setjmp.S new file mode 100644 index 0000000..ba38bd2 --- /dev/null +++ b/normal/i386/setjmp.S @@ -0,0 +1,56 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "setjmp.S" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + movl %ebx, 0(%eax) /* EBX */ + movl %esi, 4(%eax) /* ESI */ + movl %edi, 8(%eax) /* EDI */ + movl %ebp, 12(%eax) /* EBP */ + popl %ecx + movl %esp, 16(%eax) /* ESP */ + movl %ecx, 20(%eax) /* EIP */ + xorl %eax, %eax + jmp *%ecx + + +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + movl 0(%eax), %ebx + movl 4(%eax), %esi + movl 8(%eax), %edi + movl 12(%eax), %ebp + movl 16(%eax), %esp + movl 20(%eax), %ecx + + movl %edx, %eax + testl %eax, %eax + jnz 1f + incl %eax +1: jmp *%ecx + diff --git a/normal/lexer.c b/normal/lexer.c new file mode 100644 index 0000000..f500374 --- /dev/null +++ b/normal/lexer.c @@ -0,0 +1,364 @@ +/* lexer.c - The scripting lexer. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +#include "grub_script.tab.h" + +static int +check_varstate (grub_parser_state_t state) +{ + return (state == GRUB_PARSER_STATE_VARNAME + || state == GRUB_PARSER_STATE_VAR + || state == GRUB_PARSER_STATE_QVAR + || state == GRUB_PARSER_STATE_VARNAME2 + || state == GRUB_PARSER_STATE_QVARNAME + || state == GRUB_PARSER_STATE_QVARNAME2); +} + +static int +check_textstate (grub_parser_state_t state) +{ + return (state == GRUB_PARSER_STATE_TEXT + || state == GRUB_PARSER_STATE_QUOTE + || state == GRUB_PARSER_STATE_DQUOTE); +} + +struct grub_lexer_param * +grub_script_lexer_init (char *script, grub_err_t (*getline) (char **)) +{ + struct grub_lexer_param *param; + + param = grub_malloc (sizeof (*param)); + if (! param) + return 0; + + param->state = GRUB_PARSER_STATE_TEXT; + param->getline = getline; + param->refs = 0; + param->done = 0; + param->newscript = 0; + param->script = script; + param->record = 0; + param->recording = 0; + param->recordpos = 0; + param->recordlen = 0; + + return param; +} + +void +grub_script_lexer_ref (struct grub_lexer_param *state) +{ + state->refs++; +} + +void +grub_script_lexer_deref (struct grub_lexer_param *state) +{ + state->refs--; +} + +/* Start recording all characters passing through the lexer. */ +void +grub_script_lexer_record_start (struct grub_lexer_param *state) +{ + state->record = 1; + state->recordlen = 100; + state->recording = grub_malloc (state->recordlen); + state->recordpos = 0; +} + +char * +grub_script_lexer_record_stop (struct grub_lexer_param *state) +{ + state->record = 0; + + /* Delete the last character, it is a `}'. */ + if (state->recordpos > 0) + { + if (state->recording[--state->recordpos] != '}') + { + grub_printf ("Internal error while parsing menu entry"); + for (;;); /* XXX */ + } + state->recording[state->recordpos] = '\0'; + } + + return state->recording; +} + +/* When recording is enabled, record the character C as the next item + in the character stream. */ +static void +recordchar (struct grub_lexer_param *state, char c) +{ + if (state->recordpos == state->recordlen) + { + char *old = state->recording; + state->recordlen += 100; + state->recording = grub_realloc (state->recording, state->recordlen); + if (! state->recording) + { + grub_free (old); + state->record = 0; + } + } + state->recording[state->recordpos++] = c; +} + +/* Fetch the next character for the lexer. */ +static void +nextchar (struct grub_lexer_param *state) +{ + if (state->record) + recordchar (state, *state->script); + state->script++; +} + +int +grub_script_yylex2 (union YYSTYPE *yylval, + struct grub_parser_param *parsestate); + +int +grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) +{ + int r = -1; + + while (r == -1) + { + r = grub_script_yylex2 (yylval, parsestate); + if (r == ' ') + r = -1; + } + return r; +} + +int +grub_script_yylex2 (union YYSTYPE *yylval, struct grub_parser_param *parsestate) +{ + grub_parser_state_t newstate; + char use; + char *buffer; + char *bp; + struct grub_lexer_param *state = parsestate->lexerstate; + + if (state->done) + return 0; + + if (! *state->script) + { + /* Check if more tokens are requested by the parser. */ + if ((state->refs + || state->state == GRUB_PARSER_STATE_ESC) + && state->getline) + { + while (!state->script || ! grub_strlen (state->script)) + { + grub_free (state->newscript); + state->newscript = 0; + state->getline (&state->newscript); + state->script = state->newscript; + if (! state->script) + return 0; + } + grub_dprintf ("scripting", "token=`\\n'\n"); + recordchar (state, '\n'); + if (state->state != GRUB_PARSER_STATE_ESC) + return '\n'; + } + else + { + grub_free (state->newscript); + state->newscript = 0; + state->done = 1; + grub_dprintf ("scripting", "token=`\\n'\n"); + return '\n'; + } + } + + newstate = grub_parser_cmdline_state (state->state, *state->script, &use); + + /* Check if it is a text. */ + if (check_textstate (newstate)) + { + /* In case the string is not quoted, this can be a one char + length symbol. */ + if (newstate == GRUB_PARSER_STATE_TEXT) + { + switch (*state->script) + { + case ' ': + while (*state->script) + { + newstate = grub_parser_cmdline_state (state->state, + *state->script, &use); + if (! (state->state == GRUB_PARSER_STATE_TEXT + && *state->script == ' ')) + { + grub_dprintf ("scripting", "token=` '\n"); + return ' '; + } + state->state = newstate; + nextchar (state); + } + grub_dprintf ("scripting", "token=` '\n"); + return ' '; + case '{': + case '}': + case ';': + case '\n': + { + char c; + grub_dprintf ("scripting", "token=`%c'\n", *state->script); + c = *state->script;; + nextchar (state); + return c; + } + } + } + + /* XXX: Use a better size. */ + buffer = grub_script_malloc (parsestate, 2048); + if (! buffer) + return 0; + + bp = buffer; + + /* Read one token, possible quoted. */ + while (*state->script) + { + newstate = grub_parser_cmdline_state (state->state, + *state->script, &use); + + /* Check if a variable name starts. */ + if (check_varstate (newstate)) + break; + + /* If the string is not quoted or escaped, stop processing + when a special token was found. It will be recognized + next time when this function is called. */ + if (newstate == GRUB_PARSER_STATE_TEXT + && state->state != GRUB_PARSER_STATE_ESC) + { + int breakout = 0; + + switch (use) + { + case ' ': + case '{': + case '}': + case ';': + case '\n': + breakout = 1; + } + if (breakout) + break; + *(bp++) = use; + } + else if (use) + *(bp++) = use; + + state->state = newstate; + nextchar (state); + } + + /* A string of text was read in. */ + *bp = '\0'; + grub_dprintf ("scripting", "token=`%s'\n", buffer); + yylval->string = buffer; + + /* Detect some special tokens. */ + if (! grub_strcmp (buffer, "while")) + return GRUB_PARSER_TOKEN_WHILE; + else if (! grub_strcmp (buffer, "if")) + return GRUB_PARSER_TOKEN_IF; + else if (! grub_strcmp (buffer, "function")) + return GRUB_PARSER_TOKEN_FUNCTION; + else if (! grub_strcmp (buffer, "menuentry")) + return GRUB_PARSER_TOKEN_MENUENTRY; + else if (! grub_strcmp (buffer, "@")) + return GRUB_PARSER_TOKEN_MENUENTRY; + else if (! grub_strcmp (buffer, "else")) + return GRUB_PARSER_TOKEN_ELSE; + else if (! grub_strcmp (buffer, "then")) + return GRUB_PARSER_TOKEN_THEN; + else if (! grub_strcmp (buffer, "fi")) + return GRUB_PARSER_TOKEN_FI; + else + return GRUB_PARSER_TOKEN_NAME; + } + else if (newstate == GRUB_PARSER_STATE_VAR + || newstate == GRUB_PARSER_STATE_QVAR) + { + /* XXX: Use a better size. */ + buffer = grub_script_malloc (parsestate, 2096); + if (! buffer) + return 0; + + bp = buffer; + + /* This is a variable, read the variable name. */ + while (*state->script) + { + newstate = grub_parser_cmdline_state (state->state, + *state->script, &use); + + /* Check if this character is not part of the variable name + anymore. */ + if (! (check_varstate (newstate))) + { + if (state->state == GRUB_PARSER_STATE_VARNAME2 + || state->state == GRUB_PARSER_STATE_QVARNAME2) + nextchar (state); + state->state = newstate; + break; + } + + if (use) + *(bp++) = use; + nextchar (state); + state->state = newstate; + } + + *bp = '\0'; + state->state = newstate; + yylval->string = buffer; + grub_dprintf ("scripting", "vartoken=`%s'\n", buffer); + + return GRUB_PARSER_TOKEN_VAR; + } + else + { + /* There is either text or a variable name. In the case you + arrive here there is a serious problem with the lexer. */ + grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n"); + return 0; + } +} + +void +grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)), + char const *err) +{ + grub_printf ("%s\n", err); +} diff --git a/normal/main.c b/normal/main.c new file mode 100644 index 0000000..a0c0135 --- /dev/null +++ b/normal/main.c @@ -0,0 +1,648 @@ +/* main.c - the normal mode main routine */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +grub_jmp_buf grub_exit_env; + +static grub_fs_module_list_t fs_module_list = 0; + +#define GRUB_DEFAULT_HISTORY_SIZE 50 + +/* Read a line from the file FILE. */ +static char * +get_line (grub_file_t file) +{ + char c; + int pos = 0; + int literal = 0; + int comment = 0; + char *cmdline; + int max_len = 64; + + /* Initially locate some space. */ + cmdline = grub_malloc (max_len); + if (! cmdline) + return 0; + + while (1) + { + if (grub_file_read (file, &c, 1) != 1) + break; + + /* Skip all carriage returns. */ + if (c == '\r') + continue; + + /* Replace tabs with spaces. */ + if (c == '\t') + c = ' '; + + /* The previous is a backslash, then... */ + if (literal) + { + /* If it is a newline, replace it with a space and continue. */ + if (c == '\n') + { + c = ' '; + + /* Go back to overwrite the backslash. */ + if (pos > 0) + pos--; + } + + literal = 0; + } + + if (c == '\\') + literal = 1; + + if (comment) + { + if (c == '\n') + comment = 0; + } + else if (pos == 0) + { + if (c == '#') + comment = 1; + else if (! grub_isspace (c)) + cmdline[pos++] = c; + } + else + { + if (pos >= max_len) + { + char *old_cmdline = cmdline; + max_len = max_len * 2; + cmdline = grub_realloc (cmdline, max_len); + if (! cmdline) + { + grub_free (old_cmdline); + return 0; + } + } + + if (c == '\n') + break; + + cmdline[pos++] = c; + } + } + + cmdline[pos] = '\0'; + + /* If the buffer is empty, don't return anything at all. */ + if (pos == 0) + { + grub_free (cmdline); + cmdline = 0; + } + + return cmdline; +} + +static void +free_menu (grub_menu_t menu) +{ + grub_menu_entry_t entry = menu->entry_list; + + while (entry) + { + grub_menu_entry_t next_entry = entry->next; + + grub_script_free (entry->commands); + grub_free ((void *) entry->title); + grub_free ((void *) entry->sourcecode); + entry = next_entry; + } + + grub_free (menu); + grub_env_unset_data_slot ("menu"); +} + +static void +free_menu_entry_classes (struct grub_menu_entry_class *head) +{ + /* Free all the classes. */ + while (head) + { + struct grub_menu_entry_class *next; + + grub_free (head->name); + next = head->next; + grub_free (head); + head = next; + } +} + +grub_err_t +grub_normal_menu_addentry (int argc, const char **args, struct grub_script *script, + const char *sourcecode) +{ + const char *menutitle = 0; + const char *menusourcecode; + grub_menu_t menu; + grub_menu_entry_t *last; + int failed = 0; + int i; + struct grub_menu_entry_class *classes_head; /* Dummy head node for list. */ + struct grub_menu_entry_class *classes_tail; + + /* Allocate dummy head node for class list. */ + classes_head = grub_malloc (sizeof (struct grub_menu_entry_class)); + if (! classes_head) + return grub_errno; + classes_head->name = 0; + classes_head->next = 0; + classes_tail = classes_head; + + menu = grub_env_get_data_slot("menu"); + if (! menu) + return grub_error (GRUB_ERR_MENU, "no menu context"); + + last = &menu->entry_list; + + menusourcecode = grub_strdup (sourcecode); + if (! menusourcecode) + return grub_errno; + + /* Parse menu arguments. */ + for (i = 0; i < argc; i++) + { + /* Capture arguments. */ + if (grub_strncmp ("--", args[i], 2) == 0) + { + const char *arg = &args[i][2]; + + /* Handle menu class. */ + if (grub_strcmp(arg, "class") == 0) + { + char *class_name; + struct grub_menu_entry_class *new_class; + + i++; + class_name = grub_strdup (args[i]); + if (! class_name) + { + failed = 1; + break; + } + + /* Create a new class and add it at the tail of the list. */ + new_class = grub_malloc (sizeof (struct grub_menu_entry_class)); + if (! new_class) + { + grub_free (class_name); + failed = 1; + break; + } + /* Fill in the new class node. */ + new_class->name = class_name; + new_class->next = 0; + /* Link the tail to it, and make it the new tail. */ + classes_tail->next = new_class; + classes_tail = new_class; + continue; + } + else + { + /* Handle invalid argument. */ + failed = 1; + grub_error (GRUB_ERR_MENU, "invalid argument for menuentry: %s", args[i]); + break; + } + } + + /* Capture title. */ + if (! menutitle) + { + menutitle = grub_strdup (args[i]); + } + else + { + failed = 1; + grub_error (GRUB_ERR_MENU, "too many titles for menuentry: %s", args[i]); + break; + } + } + + /* Validate arguments. */ + if ((! failed) && (! menutitle)) + { + grub_error (GRUB_ERR_MENU, "menuentry is missing title"); + failed = 1; + } + + /* If argument parsing failed, free any allocated resources. */ + if (failed) + { + free_menu_entry_classes (classes_head); + grub_free ((void *) menutitle); + grub_free ((void *) menusourcecode); + + /* Here we assume that grub_error has been used to specify failure details. */ + return grub_errno; + } + + /* Add the menu entry at the end of the list. */ + while (*last) + last = &(*last)->next; + + *last = grub_malloc (sizeof (**last)); + if (! *last) + { + free_menu_entry_classes (classes_head); + grub_free ((void *) menutitle); + grub_free ((void *) menusourcecode); + return grub_errno; + } + + (*last)->commands = script; + (*last)->title = menutitle; + (*last)->classes = classes_head; + (*last)->next = 0; + (*last)->sourcecode = menusourcecode; + + menu->size++; + + return GRUB_ERR_NONE; +} + +static grub_menu_t +read_config_file (const char *config, int nested) +{ + grub_file_t file; + auto grub_err_t getline (char **line); + int currline = 0; + int errors = 0; + + grub_err_t getline (char **line) + { + currline++; + + *line = get_line (file); + if (! *line) + return grub_errno; + + return GRUB_ERR_NONE; + } + + grub_menu_t newmenu; + + newmenu = grub_env_get_data_slot ("menu"); + + if (nested || ! newmenu) + { + newmenu = grub_malloc (sizeof (*newmenu)); + if (! newmenu) + return 0; + newmenu->size = 0; + newmenu->entry_list = 0; + } + + /* Try to open the config file. */ + file = grub_file_open (config); + if (! file) + return 0; + + grub_env_set_data_slot ("menu", newmenu); + + while (1) + { + struct grub_script *parsed_script; + int startline; + char *cmdline; + + cmdline = get_line (file); + if (!cmdline) + break; + + startline = ++currline; + + /* Execute the script, line for line. */ + parsed_script = grub_script_parse (cmdline, getline); + + grub_free (cmdline); + + if (! parsed_script) + { + grub_printf ("(line %d-%d)\n", startline, currline); + errors++; + continue; + } + + /* Execute the command(s). */ + grub_script_execute (parsed_script); + + /* Ignore errors. */ + grub_errno = GRUB_ERR_NONE; + + /* The parsed script was executed, throw it away. */ + grub_script_free (parsed_script); + } + + grub_file_close (file); + + if (errors > 0) + grub_wait_after_message (); + + return newmenu; +} + +/* This starts the normal mode. */ +void +grub_enter_normal_mode (const char *config) +{ + if (grub_setjmp (grub_exit_env) == 0) + grub_normal_execute (config, 0); +} + +/* Initialize the screen. */ +void +grub_normal_init_page (void) +{ + grub_cls (); + grub_printf ("\n\ + GNU GRUB version %s\n\n", + PACKAGE_VERSION); +} + +/* Read the file command.lst for auto-loading. */ +static void +read_command_list (void) +{ + const char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + char *filename; + + filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst")); + if (filename) + { + grub_file_t file; + + grub_sprintf (filename, "%s/command.lst", prefix); + file = grub_file_open (filename); + if (file) + { + while (1) + { + char *p; + grub_command_t cmd; + char *buf = get_line (file); + + if (! buf) + break; + + if (! grub_isgraph (buf[0])) + continue; + + p = grub_strchr (buf, ':'); + if (! p) + continue; + + *p = '\0'; + while (*++p == ' ') + ; + + if (! grub_isgraph (*p)) + continue; + + cmd = grub_register_command (buf, 0, + GRUB_COMMAND_FLAG_NOT_LOADED, + 0, 0, 0); + if (! cmd) + { + grub_free (buf); + continue; + } + + cmd->module_name = grub_strdup (p); + if (! cmd->module_name) + grub_unregister_command (buf); + grub_free (buf); + } + + grub_file_close (file); + } + + grub_free (filename); + } + } + + /* Ignore errors. */ + grub_errno = GRUB_ERR_NONE; +} + +/* The auto-loading hook for filesystems. */ +static int +autoload_fs_module (void) +{ + grub_fs_module_list_t p; + + while ((p = fs_module_list) != 0) + { + if (! grub_dl_get (p->name) && grub_dl_load (p->name)) + return 1; + + fs_module_list = p->next; + grub_free (p->name); + grub_free (p); + } + + return 0; +} + +/* Read the file fs.lst for auto-loading. */ +static void +read_fs_list (void) +{ + const char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + char *filename; + + filename = grub_malloc (grub_strlen (prefix) + sizeof ("/fs.lst")); + if (filename) + { + grub_file_t file; + + grub_sprintf (filename, "%s/fs.lst", prefix); + file = grub_file_open (filename); + if (file) + { + while (1) + { + char *buf; + char *p; + char *q; + grub_fs_module_list_t fs_mod; + + buf = get_line (file); + if (! buf) + break; + + p = buf; + q = buf + grub_strlen (buf) - 1; + + /* Ignore space. */ + while (grub_isspace (*p)) + p++; + + while (p < q && grub_isspace (*q)) + *q-- = '\0'; + + /* If the line is empty, skip it. */ + if (p >= q) + continue; + + fs_mod = grub_malloc (sizeof (*fs_mod)); + if (! fs_mod) + continue; + + fs_mod->name = grub_strdup (p); + if (! fs_mod->name) + { + grub_free (fs_mod); + continue; + } + + fs_mod->next = fs_module_list; + fs_module_list = fs_mod; + } + + grub_file_close (file); + } + + grub_free (filename); + } + } + + /* Ignore errors. */ + grub_errno = GRUB_ERR_NONE; + + /* Set the hook. */ + grub_fs_autoload_hook = autoload_fs_module; +} + +/* Read the config file CONFIG and execute the menu interface or + the command-line interface. */ +void +grub_normal_execute (const char *config, int nested) +{ + grub_menu_t menu = 0; + + read_command_list (); + read_fs_list (); + + if (config) + { + menu = read_config_file (config, nested); + + /* Ignore any error. */ + grub_errno = GRUB_ERR_NONE; + } + + if (menu && menu->size) + { + grub_menu_viewer_show_menu (menu, nested); + if (nested) + free_menu (menu); + } + else + grub_cmdline_run (nested); +} + +/* Enter normal mode from rescue mode. */ +static void +grub_rescue_cmd_normal (int argc, char *argv[]) +{ + if (argc == 0) + { + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + static char *config; + const char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + config = grub_malloc (grub_strlen (prefix) + sizeof ("/grub.cfg")); + if (! config) + return; + + grub_sprintf (config, "%s/grub.cfg", prefix); + grub_enter_normal_mode (config); + grub_free (config); + } + else + grub_enter_normal_mode (0); + } + else + grub_enter_normal_mode (argv[0]); +} + +GRUB_MOD_INIT(normal) +{ + /* Normal mode shouldn't be unloaded. */ + if (mod) + grub_dl_ref (mod); + + grub_menu_viewer_register (&grub_normal_text_menu_viewer); + + grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); + + /* Register a command "normal" for the rescue mode. */ + grub_rescue_register_command ("normal", grub_rescue_cmd_normal, + "enter normal mode"); + + /* Reload terminal colors when these variables are written to. */ + grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); + grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight); + + /* Preserve hooks after context changes. */ + grub_env_export ("color_normal"); + grub_env_export ("color_highlight"); + + /* This registers some built-in commands. */ + grub_command_init (); +} + +GRUB_MOD_FINI(normal) +{ + grub_set_history (0); + grub_rescue_unregister_command ("normal"); +} + diff --git a/normal/menu.c b/normal/menu.c new file mode 100644 index 0000000..df26209 --- /dev/null +++ b/normal/menu.c @@ -0,0 +1,166 @@ +/* menu.c - General supporting functionality for menus. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Get a menu entry by its index in the entry list. */ +grub_menu_entry_t +grub_menu_get_entry (grub_menu_t menu, int no) +{ + grub_menu_entry_t e; + + for (e = menu->entry_list; e && no > 0; e = e->next, no--) + ; + + return e; +} + +/* Return the current timeout. If the variable "timeout" is not set or + invalid, return -1. */ +int +grub_menu_get_timeout (void) +{ + char *val; + int timeout; + + val = grub_env_get ("timeout"); + if (! val) + return -1; + + grub_error_push (); + + timeout = (int) grub_strtoul (val, 0, 0); + + /* If the value is invalid, unset the variable. */ + if (grub_errno != GRUB_ERR_NONE) + { + grub_env_unset ("timeout"); + grub_errno = GRUB_ERR_NONE; + timeout = -1; + } + + grub_error_pop (); + + return timeout; +} + +/* Set current timeout in the variable "timeout". */ +void +grub_menu_set_timeout (int timeout) +{ + /* Ignore TIMEOUT if it is zero, because it will be unset really soon. */ + if (timeout > 0) + { + char buf[16]; + + grub_sprintf (buf, "%d", timeout); + grub_env_set ("timeout", buf); + } +} + +/* Get the first entry number from the value of the environment variable NAME, + which is a space-separated list of nonnegative integers. The entry number + which is returned is stripped from the value of NAME. If no entry number + can be found, -1 is returned. */ +static int +get_and_remove_first_entry_number (const char *name) +{ + char *val; + char *tail; + int entry; + + val = grub_env_get (name); + if (! val) + return -1; + + grub_error_push (); + + entry = (int) grub_strtoul (val, &tail, 0); + + if (grub_errno == GRUB_ERR_NONE) + { + /* Skip whitespace to find the next digit. */ + while (*tail && grub_isspace (*tail)) + tail++; + grub_env_set (name, tail); + } + else + { + grub_env_unset (name); + grub_errno = GRUB_ERR_NONE; + entry = -1; + } + + grub_error_pop (); + + return entry; +} + +/* Run a menu entry. */ +void +grub_menu_execute_entry(grub_menu_entry_t entry) +{ + grub_script_execute (entry->commands); + + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ + grub_command_execute ("boot", 0); +} + +/* Execute ENTRY from the menu MENU, falling back to entries specified + in the environment variable "fallback" if it fails. CALLBACK is a + pointer to a struct of function pointers which are used to allow the + caller provide feedback to the user. */ +void +grub_menu_execute_with_fallback (grub_menu_t menu, + grub_menu_entry_t entry, + grub_menu_execute_callback_t callback, + void *callback_data) +{ + int fallback_entry; + + callback->notify_booting (entry, callback_data); + + grub_menu_execute_entry (entry); + + /* Deal with fallback entries. */ + while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) + >= 0) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + entry = grub_menu_get_entry (menu, fallback_entry); + callback->notify_fallback (entry, callback_data); + grub_menu_execute_entry (entry); + /* If the function call to execute the entry returns at all, then this is + taken to indicate a boot failure. For menu entries that do something + other than actually boot an operating system, this could assume + incorrectly that something failed. */ + } + + callback->notify_failure (callback_data); +} diff --git a/normal/menu_entry.c b/normal/menu_entry.c new file mode 100644 index 0000000..a9c1788 --- /dev/null +++ b/normal/menu_entry.c @@ -0,0 +1,1186 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +enum update_mode + { + NO_LINE, + SINGLE_LINE, + ALL_LINES + }; + +struct line +{ + /* The line buffer. */ + char *buf; + /* The length of the line. */ + int len; + /* The maximum length of the line. */ + int max_len; +}; + +struct screen +{ + /* The array of lines. */ + struct line *lines; + /* The number of lines. */ + int num_lines; + /* The current column. */ + int column; + /* The real column. */ + int real_column; + /* The current line. */ + int line; + /* The X coordinate. */ + int x; + /* The Y coordinate. */ + int y; + /* The kill buffer. */ + char *killed_text; + /* The flag of a completion window. */ + int completion_shown; +}; + +/* Used for storing completion items temporarily. */ +static struct line completion_buffer; + +/* Initialize a line. */ +static int +init_line (struct line *linep) +{ + linep->len = 0; + linep->max_len = 80; /* XXX */ + linep->buf = grub_malloc (linep->max_len); + if (! linep->buf) + return 0; + + return 1; +} + +/* Allocate extra space if necessary. */ +static int +ensure_space (struct line *linep, int extra) +{ + if (linep->max_len < linep->len + extra) + { + linep->max_len = linep->len + extra + 80; /* XXX */ + linep->buf = grub_realloc (linep->buf, linep->max_len + 1); + if (! linep->buf) + return 0; + } + + return 1; +} + +/* Return the number of lines occupied by this line on the screen. */ +static int +get_logical_num_lines (struct line *linep) +{ + return (linep->len / GRUB_TERM_ENTRY_WIDTH) + 1; +} + +/* Print a line. */ +static void +print_line (struct line *linep, int offset, int start, int y) +{ + int i; + char *p; + + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1, + y + GRUB_TERM_FIRST_ENTRY_Y); + + for (p = linep->buf + offset + start, i = start; + i < GRUB_TERM_ENTRY_WIDTH && offset + i < linep->len; + p++, i++) + grub_putchar (*p); + + for (; i < GRUB_TERM_ENTRY_WIDTH; i++) + grub_putchar (' '); + + if (linep->len >= offset + GRUB_TERM_ENTRY_WIDTH) + grub_putchar ('\\'); + else + grub_putchar (' '); +} + +/* Print an empty line. */ +static void +print_empty_line (int y) +{ + int i; + + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, + y + GRUB_TERM_FIRST_ENTRY_Y); + + for (i = 0; i < GRUB_TERM_ENTRY_WIDTH + 1; i++) + grub_putchar (' '); +} + +/* Print an up arrow. */ +static void +print_up (int flag) +{ + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, + GRUB_TERM_FIRST_ENTRY_Y); + + if (flag) + grub_putcode (GRUB_TERM_DISP_UP); + else + grub_putchar (' '); +} + +/* Print a down arrow. */ +static void +print_down (int flag) +{ + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, + GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES); + + if (flag) + grub_putcode (GRUB_TERM_DISP_DOWN); + else + grub_putchar (' '); +} + +/* Draw the lines of the screen SCREEN. */ +static void +update_screen (struct screen *screen, int region_start, int region_column, + int up, int down, enum update_mode mode) +{ + int up_flag = 0; + int down_flag = 0; + int y; + int i; + struct line *linep; + + /* Check if scrolling is necessary. */ + if (screen->y < 0 || screen->y >= GRUB_TERM_NUM_ENTRIES) + { + if (screen->y < 0) + screen->y = 0; + else + screen->y = GRUB_TERM_NUM_ENTRIES - 1; + + region_start = 0; + region_column = 0; + up = 1; + down = 1; + mode = ALL_LINES; + } + + if (mode != NO_LINE) + { + /* Draw lines. This code is tricky, because this must calculate logical + positions. */ + y = screen->y - screen->column / GRUB_TERM_ENTRY_WIDTH; + i = screen->line; + linep = screen->lines + i; + while (y > 0) + { + i--; + linep--; + y -= get_logical_num_lines (linep); + } + + if (y < 0 || i > 0) + up_flag = 1; + + do + { + int column; + + for (column = 0; + column <= linep->len && y < GRUB_TERM_NUM_ENTRIES; + column += GRUB_TERM_ENTRY_WIDTH, y++) + { + if (y < 0) + continue; + + if (i == region_start) + { + if (region_column >= column + && region_column < column + GRUB_TERM_ENTRY_WIDTH) + print_line (linep, column, region_column - column, y); + else if (region_column < column) + print_line (linep, column, 0, y); + } + else if (i > region_start && mode == ALL_LINES) + print_line (linep, column, 0, y); + } + + if (y == GRUB_TERM_NUM_ENTRIES) + { + if (column <= linep->len || i + 1 < screen->num_lines) + down_flag = 1; + } + + linep++; + i++; + + if (mode == ALL_LINES && i == screen->num_lines) + for (; y < GRUB_TERM_NUM_ENTRIES; y++) + print_empty_line (y); + + } + while (y < GRUB_TERM_NUM_ENTRIES); + + /* Draw up and down arrows. */ + if (up) + print_up (up_flag); + if (down) + print_down (down_flag); + } + + /* Place the cursor. */ + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 + screen->x, + GRUB_TERM_FIRST_ENTRY_Y + screen->y); + + grub_refresh (); +} + +/* Insert the string S into the screen SCREEN. This updates the cursor + position and redraw the screen. Return zero if fails. */ +static int +insert_string (struct screen *screen, char *s, int update) +{ + int region_start = screen->num_lines; + int region_column = 0; + int down = 0; + enum update_mode mode = NO_LINE; + + while (*s) + { + if (*s == '\n') + { + /* LF is special because it creates a new line. */ + struct line *current_linep; + struct line *next_linep; + int size; + + /* Make a new line. */ + screen->num_lines++; + screen->lines = grub_realloc (screen->lines, + screen->num_lines + * sizeof (struct line)); + if (! screen->lines) + return 0; + + /* Scroll down. */ + grub_memmove (screen->lines + screen->line + 2, + screen->lines + screen->line + 1, + ((screen->num_lines - screen->line - 2) + * sizeof (struct line))); + + if (! init_line (screen->lines + screen->line + 1)) + return 0; + + /* Fold the line. */ + current_linep = screen->lines + screen->line; + next_linep = current_linep + 1; + size = current_linep->len - screen->column; + + if (! ensure_space (next_linep, size)) + return 0; + + grub_memmove (next_linep->buf, + current_linep->buf + screen->column, + size); + current_linep->len = screen->column; + next_linep->len = size; + + /* Update a dirty region. */ + if (region_start > screen->line) + { + region_start = screen->line; + region_column = screen->column; + } + + mode = ALL_LINES; + down = 1; /* XXX not optimal. */ + + /* Move the cursor. */ + screen->column = screen->real_column = 0; + screen->line++; + screen->x = 0; + screen->y++; + + s++; + } + else + { + /* All but LF. */ + char *p; + struct line *current_linep; + int size; + int orig_num, new_num; + + /* Find a string delimited by LF. */ + p = grub_strchr (s, '\n'); + if (! p) + p = s + grub_strlen (s); + + /* Insert the string. */ + current_linep = screen->lines + screen->line; + size = p - s; + if (! ensure_space (current_linep, size)) + return 0; + + grub_memmove (current_linep->buf + screen->column + size, + current_linep->buf + screen->column, + current_linep->len - screen->column); + grub_memmove (current_linep->buf + screen->column, + s, + size); + orig_num = get_logical_num_lines (current_linep); + current_linep->len += size; + new_num = get_logical_num_lines (current_linep); + + /* Update the dirty region. */ + if (region_start > screen->line) + { + region_start = screen->line; + region_column = screen->column; + } + + if (orig_num != new_num) + { + mode = ALL_LINES; + down = 1; /* XXX not optimal. */ + } + else if (mode != ALL_LINES) + mode = SINGLE_LINE; + + /* Move the cursor. */ + screen->column += size; + screen->real_column = screen->column; + screen->x += size; + screen->y += screen->x / GRUB_TERM_ENTRY_WIDTH; + screen->x %= GRUB_TERM_ENTRY_WIDTH; + + s = p; + } + } + + if (update) + update_screen (screen, region_start, region_column, 0, down, mode); + + return 1; +} + +/* Release the resource allocated for SCREEN. */ +static void +destroy_screen (struct screen *screen) +{ + int i; + + if (screen->lines) + for (i = 0; i < screen->num_lines; i++) + { + struct line *linep = screen->lines + i; + + if (linep) + grub_free (linep->buf); + } + + grub_free (screen->killed_text); + grub_free (screen->lines); + grub_free (screen); +} + +/* Make a new screen. */ +static struct screen * +make_screen (grub_menu_entry_t entry) +{ + struct screen *screen; + + /* Initialize the screen. */ + screen = grub_malloc (sizeof (*screen)); + if (! screen) + return 0; + + screen->num_lines = 1; + screen->column = 0; + screen->real_column = 0; + screen->line = 0; + screen->x = 0; + screen->y = 0; + screen->killed_text = 0; + screen->completion_shown = 0; + screen->lines = grub_malloc (sizeof (struct line)); + if (! screen->lines) + goto fail; + + /* Initialize the first line which must be always present. */ + if (! init_line (screen->lines)) + goto fail; + + insert_string (screen, (char *) entry->sourcecode, 0); + + /* Reset the cursor position. */ + screen->column = 0; + screen->real_column = 0; + screen->line = 0; + screen->x = 0; + screen->y = 0; + + return screen; + + fail: + destroy_screen (screen); + return 0; +} + +static int +forward_char (struct screen *screen, int update) +{ + struct line *linep; + + linep = screen->lines + screen->line; + if (screen->column < linep->len) + { + screen->column++; + screen->x++; + if (screen->x == GRUB_TERM_ENTRY_WIDTH) + { + screen->x = 0; + screen->y++; + } + } + else if (screen->num_lines > screen->line + 1) + { + screen->column = 0; + screen->line++; + screen->x = 0; + screen->y++; + } + + screen->real_column = screen->column; + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + return 1; +} + +static int +backward_char (struct screen *screen, int update) +{ + if (screen->column > 0) + { + screen->column--; + screen->x--; + if (screen->x == -1) + { + screen->x = GRUB_TERM_ENTRY_WIDTH - 1; + screen->y--; + } + } + else if (screen->line > 0) + { + struct line *linep; + + screen->line--; + linep = screen->lines + screen->line; + screen->column = linep->len; + screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH; + screen->y--; + } + + screen->real_column = screen->column; + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + + return 1; +} + +static int +previous_line (struct screen *screen, int update) +{ + if (screen->line > 0) + { + struct line *linep; + int dy; + + /* How many physical lines from the current position + to the first physical line? */ + dy = screen->column / GRUB_TERM_ENTRY_WIDTH; + + screen->line--; + + linep = screen->lines + screen->line; + if (linep->len < screen->real_column) + screen->column = linep->len; + else + screen->column = screen->real_column; + + /* How many physical lines from the current position + to the last physical line? */ + dy += (linep->len / GRUB_TERM_ENTRY_WIDTH + - screen->column / GRUB_TERM_ENTRY_WIDTH); + + screen->y -= dy + 1; + screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH; + } + else + { + screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH; + screen->column = 0; + screen->x = 0; + } + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + + return 1; +} + +static int +next_line (struct screen *screen, int update) +{ + if (screen->line < screen->num_lines - 1) + { + struct line *linep; + int dy; + + /* How many physical lines from the current position + to the last physical line? */ + linep = screen->lines + screen->line; + dy = (linep->len / GRUB_TERM_ENTRY_WIDTH + - screen->column / GRUB_TERM_ENTRY_WIDTH); + + screen->line++; + + linep++; + if (linep->len < screen->real_column) + screen->column = linep->len; + else + screen->column = screen->real_column; + + /* How many physical lines from the current position + to the first physical line? */ + dy += screen->column / GRUB_TERM_ENTRY_WIDTH; + + screen->y += dy + 1; + screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH; + } + else + { + struct line *linep; + + linep = screen->lines + screen->line; + screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH + - screen->column / GRUB_TERM_ENTRY_WIDTH); + screen->column = linep->len; + screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH; + } + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + + return 1; +} + +static int +beginning_of_line (struct screen *screen, int update) +{ + screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH; + screen->column = screen->real_column = 0; + screen->x = 0; + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + + return 1; +} + +static int +end_of_line (struct screen *screen, int update) +{ + struct line *linep; + + linep = screen->lines + screen->line; + screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH + - screen->column / GRUB_TERM_ENTRY_WIDTH); + screen->column = screen->real_column = linep->len; + screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH; + + if (update) + update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE); + + return 1; +} + +static int +delete_char (struct screen *screen, int update) +{ + struct line *linep; + enum update_mode mode = NO_LINE; + int start = screen->num_lines; + int column = 0; + int down = 0; + + linep = screen->lines + screen->line; + if (linep->len > screen->column) + { + int orig_num, new_num; + + orig_num = get_logical_num_lines (linep); + + grub_memmove (linep->buf + screen->column, + linep->buf + screen->column + 1, + linep->len - screen->column - 1); + linep->len--; + + new_num = get_logical_num_lines (linep); + + if (orig_num != new_num) + mode = ALL_LINES; + else + mode = SINGLE_LINE; + + start = screen->line; + column = screen->column; + } + else if (screen->num_lines > screen->line + 1) + { + struct line *next_linep; + + next_linep = linep + 1; + if (! ensure_space (linep, next_linep->len)) + return 0; + + grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len); + linep->len += next_linep->len; + + grub_free (next_linep->buf); + grub_memmove (next_linep, + next_linep + 1, + (screen->num_lines - screen->line - 2) + * sizeof (struct line)); + screen->num_lines--; + + mode = ALL_LINES; + start = screen->line; + column = screen->column; + down = 1; + } + + screen->real_column = screen->column; + + if (update) + update_screen (screen, start, column, 0, down, mode); + + return 1; +} + +static int +backward_delete_char (struct screen *screen, int update) +{ + int saved_column; + int saved_line; + + saved_column = screen->column; + saved_line = screen->line; + + if (! backward_char (screen, 0)) + return 0; + + if (saved_column != screen->column || saved_line != screen->line) + if (! delete_char (screen, update)) + return 0; + + return 1; +} + +static int +kill_line (struct screen *screen, int continuous, int update) +{ + struct line *linep; + char *p; + int size; + int offset; + + p = screen->killed_text; + if (! continuous && p) + p[0] = '\0'; + + linep = screen->lines + screen->line; + size = linep->len - screen->column; + + if (p) + offset = grub_strlen (p); + else + offset = 0; + + if (size > 0) + { + enum update_mode mode = SINGLE_LINE; + int down = 0; + int orig_num, new_num; + + p = grub_realloc (p, offset + size + 1); + if (! p) + return 0; + + grub_memmove (p + offset, linep->buf + screen->column, size); + p[offset + size - 1] = '\0'; + + screen->killed_text = p; + + orig_num = get_logical_num_lines (linep); + linep->len = screen->column; + new_num = get_logical_num_lines (linep); + + if (orig_num != new_num) + { + mode = ALL_LINES; + down = 1; + } + + if (update) + update_screen (screen, screen->line, screen->column, 0, down, mode); + } + else if (screen->line + 1 < screen->num_lines) + { + p = grub_realloc (p, offset + 1 + 1); + if (! p) + return 0; + + p[offset] = '\n'; + p[offset + 1] = '\0'; + + screen->killed_text = p; + + return delete_char (screen, update); + } + + return 1; +} + +static int +yank (struct screen *screen, int update) +{ + if (screen->killed_text) + return insert_string (screen, screen->killed_text, update); + + return 1; +} + +static int +open_line (struct screen *screen, int update) +{ + int saved_y = screen->y; + + if (! insert_string (screen, "\n", 0)) + return 0; + + if (! backward_char (screen, 0)) + return 0; + + screen->y = saved_y; + + if (update) + update_screen (screen, screen->line, screen->column, 0, 1, ALL_LINES); + + return 1; +} + +/* A completion hook to print items. */ +static void +store_completion (const char *item, grub_completion_type_t type, int count) +{ + char *p; + + if (count == 0) + { + /* If this is the first time, print a label. */ + const char *what; + + switch (type) + { + case GRUB_COMPLETION_TYPE_COMMAND: + what = "commands"; + break; + case GRUB_COMPLETION_TYPE_DEVICE: + what = "devices"; + break; + case GRUB_COMPLETION_TYPE_FILE: + what = "files"; + break; + case GRUB_COMPLETION_TYPE_PARTITION: + what = "partitions"; + break; + case GRUB_COMPLETION_TYPE_ARGUMENT: + what = "arguments"; + break; + default: + what = "things"; + break; + } + + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); + grub_printf (" Possible %s are:\n ", what); + } + + /* Make sure that the completion buffer has enough room. */ + if (completion_buffer.max_len < (completion_buffer.len + + (int) grub_strlen (item) + 1 + 1)) + { + grub_size_t new_len; + + new_len = completion_buffer.len + grub_strlen (item) + 80; + p = grub_realloc (completion_buffer.buf, new_len); + if (! p) + { + /* Possibly not fatal. */ + grub_errno = GRUB_ERR_NONE; + return; + } + p[completion_buffer.len] = 0; + completion_buffer.buf = p; + completion_buffer.max_len = new_len; + } + + p = completion_buffer.buf + completion_buffer.len; + if (completion_buffer.len != 0) + { + *p++ = ' '; + completion_buffer.len++; + } + grub_strcpy (p, item); + completion_buffer.len += grub_strlen (item); +} + +static int +complete (struct screen *screen, int continuous, int update) +{ + grub_uint16_t pos; + char saved_char; + struct line *linep; + int restore; + char *insert; + static int count = -1; + + if (continuous) + count++; + else + count = 0; + + pos = grub_getxy (); + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); + + completion_buffer.buf = 0; + completion_buffer.len = 0; + completion_buffer.max_len = 0; + + linep = screen->lines + screen->line; + saved_char = linep->buf[screen->column]; + linep->buf[screen->column] = '\0'; + + insert = grub_normal_do_completion (linep->buf, &restore, store_completion); + + linep->buf[screen->column] = saved_char; + + if (restore) + { + char *p = completion_buffer.buf; + + screen->completion_shown = 1; + + if (p) + { + int num_sections = ((completion_buffer.len + GRUB_TERM_WIDTH - 8 - 1) + / (GRUB_TERM_WIDTH - 8)); + char *endp; + + p += (count % num_sections) * (GRUB_TERM_WIDTH - 8); + endp = p + (GRUB_TERM_WIDTH - 8); + + if (p != completion_buffer.buf) + grub_putcode (GRUB_TERM_DISP_LEFT); + else + grub_putchar (' '); + + while (*p && p < endp) + grub_putchar (*p++); + + if (*p) + grub_putcode (GRUB_TERM_DISP_RIGHT); + } + } + + grub_gotoxy (pos >> 8, pos & 0xFF); + + if (insert) + { + insert_string (screen, insert, update); + count = -1; + grub_free (insert); + } + else if (update) + grub_refresh (); + + grub_free (completion_buffer.buf); + return 1; +} + +/* Clear displayed completions. */ +static void +clear_completions (void) +{ + grub_uint16_t pos; + int i, j; + + pos = grub_getxy (); + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); + + for (i = 0; i < 2; i++) + { + for (j = 0; j < GRUB_TERM_WIDTH - 1; j++) + grub_putchar (' '); + grub_putchar ('\n'); + } + + grub_gotoxy (pos >> 8, pos & 0xFF); + grub_refresh (); +} + +/* Execute the command list in the screen SCREEN. */ +static int +run (struct screen *screen) +{ + struct grub_script *parsed_script = 0; + int currline = 0; + char *nextline; + + auto grub_err_t editor_getline (char **line); + grub_err_t editor_getline (char **line) + { + struct line *linep = screen->lines + currline; + char *p; + + if (currline > screen->num_lines) + { + *line = 0; + return 0; + } + + /* Trim down space characters. */ + for (p = linep->buf + linep->len - 1; + p >= linep->buf && grub_isspace (*p); + p--) + ; + *++p = '\0'; + + linep->len = p - linep->buf; + for (p = linep->buf; grub_isspace (*p); p++) + ; + *line = grub_strdup (p); + currline++; + return 0; + } + + grub_cls (); + grub_printf (" Booting a command list\n\n"); + + + /* Execute the script, line for line. */ + while (currline < screen->num_lines) + { + editor_getline (&nextline); + parsed_script = grub_script_parse (nextline, editor_getline); + if (parsed_script) + { + /* Execute the command(s). */ + grub_script_execute (parsed_script); + + /* The parsed script was executed, throw it away. */ + grub_script_free (parsed_script); + } + else + break; + } + + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ + grub_command_execute ("boot", 0); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_wait_after_message (); + } + + return 1; +} + +/* Edit a menu entry with an Emacs-like interface. */ +void +grub_menu_entry_run (grub_menu_entry_t entry) +{ + struct screen *screen; + int prev_c; + + screen = make_screen (entry); + if (! screen) + return; + + refresh: + /* Draw the screen. */ + grub_menu_init_page (0, 1); + update_screen (screen, 0, 0, 1, 1, ALL_LINES); + grub_setcursor (1); + prev_c = '\0'; + + while (1) + { + int c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + + if (screen->completion_shown) + { + clear_completions (); + screen->completion_shown = 0; + } + + switch (c) + { + case 16: /* C-p */ + if (! previous_line (screen, 1)) + goto fail; + break; + + case 14: /* C-n */ + if (! next_line (screen, 1)) + goto fail; + break; + + case 6: /* C-f */ + if (! forward_char (screen, 1)) + goto fail; + break; + + case 2: /* C-b */ + if (! backward_char (screen, 1)) + goto fail; + break; + + case 1: /* C-a */ + if (! beginning_of_line (screen, 1)) + goto fail; + break; + + case 5: /* C-e */ + if (! end_of_line (screen, 1)) + goto fail; + break; + + case '\t': /* C-i */ + if (! complete (screen, prev_c == c, 1)) + goto fail; + break; + + case 4: /* C-d */ + if (! delete_char (screen, 1)) + goto fail; + break; + + case 8: /* C-h */ + if (! backward_delete_char (screen, 1)) + goto fail; + break; + + case 11: /* C-k */ + if (! kill_line (screen, prev_c == c, 1)) + goto fail; + break; + + case 21: /* C-u */ + /* FIXME: What behavior is good for this key? */ + break; + + case 25: /* C-y */ + if (! yank (screen, 1)) + goto fail; + break; + + case 12: /* C-l */ + /* FIXME: centering. */ + goto refresh; + + case 15: /* C-o */ + if (! open_line (screen, 1)) + goto fail; + break; + + case '\n': + case '\r': + if (! insert_string (screen, "\n", 1)) + goto fail; + break; + + case '\e': + destroy_screen (screen); + return; + + case 3: /* C-c */ + grub_cmdline_run (1); + goto refresh; + + case 24: /* C-x */ + if (! run (screen)) + goto fail; + goto refresh; + + case 18: /* C-r */ + case 19: /* C-s */ + case 20: /* C-t */ + /* FIXME */ + break; + + default: + if (grub_isprint (c)) + { + char buf[2]; + + buf[0] = c; + buf[1] = '\0'; + if (! insert_string (screen, buf, 1)) + goto fail; + } + break; + } + + prev_c = c; + } + + fail: + destroy_screen (screen); + + grub_cls (); + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_printf ("\nPress any key to continue..."); + (void) grub_getkey (); +} diff --git a/normal/menu_text.c b/normal/menu_text.c new file mode 100644 index 0000000..cb22982 --- /dev/null +++ b/normal/menu_text.c @@ -0,0 +1,600 @@ +/* menu_text.c - Basic text menu implementation. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Time to delay after displaying an error message about a default/fallback + entry failing to boot. */ +#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500 + +static grub_uint8_t grub_color_menu_normal; +static grub_uint8_t grub_color_menu_highlight; + +/* Wait until the user pushes any key so that the user + can see what happened. */ +void +grub_wait_after_message (void) +{ + grub_printf ("\nPress any key to continue..."); + (void) grub_getkey (); +} + +static void +draw_border (void) +{ + unsigned i; + + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + + grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y); + grub_putcode (GRUB_TERM_DISP_UL); + for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++) + grub_putcode (GRUB_TERM_DISP_HLINE); + grub_putcode (GRUB_TERM_DISP_UR); + + for (i = 0; i < (unsigned) GRUB_TERM_NUM_ENTRIES; i++) + { + grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1); + grub_putcode (GRUB_TERM_DISP_VLINE); + grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1, + GRUB_TERM_TOP_BORDER_Y + i + 1); + grub_putcode (GRUB_TERM_DISP_VLINE); + } + + grub_gotoxy (GRUB_TERM_MARGIN, + GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1); + grub_putcode (GRUB_TERM_DISP_LL); + for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++) + grub_putcode (GRUB_TERM_DISP_HLINE); + grub_putcode (GRUB_TERM_DISP_LR); + + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + + grub_gotoxy (GRUB_TERM_MARGIN, + (GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + + GRUB_TERM_MARGIN + 1)); +} + +static void +print_message (int nested, int edit) +{ + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + + if (edit) + { + grub_printf ("\n\ + Minimum Emacs-like screen editing is supported. TAB lists\n\ + completions. Press Ctrl-x to boot, Ctrl-c for a command-line\n\ + or ESC to return menu."); + } + else + { + grub_printf ("\n\ + Use the %C and %C keys to select which entry is highlighted.\n", + (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN); + grub_printf ("\ + Press enter to boot the selected OS, \'e\' to edit the\n\ + commands before booting or \'c\' for a command-line."); + if (nested) + grub_printf ("\n\ + ESC to return previous menu."); + } +} + +static void +print_entry (int y, int highlight, grub_menu_entry_t entry) +{ + int x; + const char *title; + grub_size_t title_len; + grub_ssize_t len; + grub_uint32_t *unicode_title; + grub_ssize_t i; + grub_uint8_t old_color_normal, old_color_highlight; + + title = entry ? entry->title : ""; + title_len = grub_strlen (title); + unicode_title = grub_malloc (title_len * sizeof (*unicode_title)); + if (! unicode_title) + /* XXX How to show this error? */ + return; + + len = grub_utf8_to_ucs4 (unicode_title, title_len, + (grub_uint8_t *) title, -1, 0); + if (len < 0) + { + /* It is an invalid sequence. */ + grub_free (unicode_title); + return; + } + + grub_getcolor (&old_color_normal, &old_color_highlight); + grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight); + grub_setcolorstate (highlight + ? GRUB_TERM_COLOR_HIGHLIGHT + : GRUB_TERM_COLOR_NORMAL); + + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y); + + for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0; + x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN; + i++) + { + if (i < len + && x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH + - GRUB_TERM_MARGIN - 1)) + { + grub_ssize_t width; + + width = grub_getcharwidth (unicode_title[i]); + + if (x + width > (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH + - GRUB_TERM_MARGIN - 1)) + grub_putcode (GRUB_TERM_DISP_RIGHT); + else + grub_putcode (unicode_title[i]); + + x += width; + } + else + { + grub_putchar (' '); + x++; + } + } + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + grub_putchar (' '); + + grub_gotoxy (GRUB_TERM_CURSOR_X, y); + + grub_setcolor (old_color_normal, old_color_highlight); + grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); + grub_free (unicode_title); +} + +static void +print_entries (grub_menu_t menu, int first, int offset) +{ + grub_menu_entry_t e; + int i; + + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, + GRUB_TERM_FIRST_ENTRY_Y); + + if (first) + grub_putcode (GRUB_TERM_DISP_UP); + else + grub_putchar (' '); + + e = grub_menu_get_entry (menu, first); + + for (i = 0; i < GRUB_TERM_NUM_ENTRIES; i++) + { + print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e); + if (e) + e = e->next; + } + + grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, + GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES); + + if (e) + grub_putcode (GRUB_TERM_DISP_DOWN); + else + grub_putchar (' '); + + grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); +} + +/* Initialize the screen. If NESTED is non-zero, assume that this menu + is run from another menu or a command-line. If EDIT is non-zero, show + a message for the menu entry editor. */ +void +grub_menu_init_page (int nested, int edit) +{ + grub_uint8_t old_color_normal, old_color_highlight; + + grub_getcolor (&old_color_normal, &old_color_highlight); + + /* By default, use the same colors for the menu. */ + grub_color_menu_normal = old_color_normal; + grub_color_menu_highlight = old_color_highlight; + + /* Then give user a chance to replace them. */ + grub_parse_color_name_pair (&grub_color_menu_normal, grub_env_get ("menu_color_normal")); + grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight")); + + grub_normal_init_page (); + grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight); + draw_border (); + grub_setcolor (old_color_normal, old_color_highlight); + print_message (nested, edit); +} + +/* Get the entry number from the variable NAME. */ +static int +get_entry_number (const char *name) +{ + char *val; + int entry; + + val = grub_env_get (name); + if (! val) + return -1; + + grub_error_push (); + + entry = (int) grub_strtoul (val, 0, 0); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_errno = GRUB_ERR_NONE; + entry = -1; + } + + grub_error_pop (); + + return entry; +} + +static void +print_timeout (int timeout, int offset, int second_stage) +{ + /* NOTE: Do not remove the trailing space characters. + They are required to clear the line. */ + char *msg = " The highlighted entry will be booted automatically in %ds. "; + char *msg_end = grub_strchr (msg, '%'); + + grub_gotoxy (second_stage ? (msg_end - msg) : 0, GRUB_TERM_HEIGHT - 3); + grub_printf (second_stage ? msg_end : msg, timeout); + grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); + grub_refresh (); +}; + +/* Show the menu and handle menu entry selection. Returns the menu entry + index that should be executed or -1 if no entry should be executed (e.g., + Esc pressed to exit a sub-menu or switching menu viewers). + If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu + entry to be executed is a result of an automatic default selection because + of the timeout. */ +static int +run_menu (grub_menu_t menu, int nested, int *auto_boot) +{ + int first, offset; + grub_uint64_t saved_time; + int default_entry; + int timeout; + + first = 0; + + default_entry = get_entry_number ("default"); + + /* If DEFAULT_ENTRY is not within the menu entries, fall back to + the first entry. */ + if (default_entry < 0 || default_entry >= menu->size) + default_entry = 0; + + /* If timeout is 0, drawing is pointless (and ugly). */ + if (grub_menu_get_timeout () == 0) + { + *auto_boot = 1; + return default_entry; + } + + offset = default_entry; + if (offset > GRUB_TERM_NUM_ENTRIES - 1) + { + first = offset - (GRUB_TERM_NUM_ENTRIES - 1); + offset = GRUB_TERM_NUM_ENTRIES - 1; + } + + /* Initialize the time. */ + saved_time = grub_get_time_ms (); + + refresh: + grub_setcursor (0); + grub_menu_init_page (nested, 0); + print_entries (menu, first, offset); + grub_refresh (); + + timeout = grub_menu_get_timeout (); + + if (timeout > 0) + print_timeout (timeout, offset, 0); + + while (1) + { + int c; + timeout = grub_menu_get_timeout (); + + if (timeout > 0) + { + grub_uint64_t current_time; + + current_time = grub_get_time_ms (); + if (current_time - saved_time >= 1000) + { + timeout--; + grub_menu_set_timeout (timeout); + saved_time = current_time; + print_timeout (timeout, offset, 1); + } + } + + if (timeout == 0) + { + grub_env_unset ("timeout"); + *auto_boot = 1; + return default_entry; + } + + if (grub_checkkey () >= 0 || timeout < 0) + { + c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + + if (timeout >= 0) + { + grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); + grub_printf ("\ + "); + grub_env_unset ("timeout"); + grub_env_unset ("fallback"); + grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); + } + + switch (c) + { + case GRUB_TERM_HOME: + first = 0; + offset = 0; + print_entries (menu, first, offset); + break; + + case GRUB_TERM_END: + offset = menu->size - 1; + if (offset > GRUB_TERM_NUM_ENTRIES - 1) + { + first = offset - (GRUB_TERM_NUM_ENTRIES - 1); + offset = GRUB_TERM_NUM_ENTRIES - 1; + } + print_entries (menu, first, offset); + break; + + case GRUB_TERM_UP: + case '^': + if (offset > 0) + { + print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, + grub_menu_get_entry (menu, first + offset)); + offset--; + print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, + grub_menu_get_entry (menu, first + offset)); + } + else if (first > 0) + { + first--; + print_entries (menu, first, offset); + } + break; + + case GRUB_TERM_DOWN: + case 'v': + if (menu->size > first + offset + 1) + { + if (offset < GRUB_TERM_NUM_ENTRIES - 1) + { + print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, + grub_menu_get_entry (menu, first + offset)); + offset++; + print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, + grub_menu_get_entry (menu, first + offset)); + } + else + { + first++; + print_entries (menu, first, offset); + } + } + break; + + case GRUB_TERM_PPAGE: + if (first == 0) + { + offset = 0; + } + else + { + first -= GRUB_TERM_NUM_ENTRIES; + + if (first < 0) + { + offset += first; + first = 0; + } + } + print_entries (menu, first, offset); + break; + + case GRUB_TERM_NPAGE: + if (offset == 0) + { + offset += GRUB_TERM_NUM_ENTRIES - 1; + if (first + offset >= menu->size) + { + offset = menu->size - first - 1; + } + } + else + { + first += GRUB_TERM_NUM_ENTRIES; + + if (first + offset >= menu->size) + { + first -= GRUB_TERM_NUM_ENTRIES; + offset += GRUB_TERM_NUM_ENTRIES; + + if (offset > menu->size - 1 || + offset > GRUB_TERM_NUM_ENTRIES - 1) + { + offset = menu->size - first - 1; + } + if (offset > GRUB_TERM_NUM_ENTRIES) + { + first += offset - GRUB_TERM_NUM_ENTRIES + 1; + offset = GRUB_TERM_NUM_ENTRIES - 1; + } + } + } + print_entries (menu, first, offset); + break; + + case '\n': + case '\r': + case 6: + grub_setcursor (1); + *auto_boot = 0; + return first + offset; + + case '\e': + if (nested) + { + grub_setcursor (1); + return -1; + } + break; + + case 'c': + grub_cmdline_run (1); + goto refresh; + + case 'e': + { + grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset); + if (e) + grub_menu_entry_run (e); + } + goto refresh; + + default: + break; + } + + grub_refresh (); + } + } + + /* Never reach here. */ + return -1; +} + +/* Callback invoked immediately before a menu entry is executed. */ +static void +notify_booting (grub_menu_entry_t entry, + void *userdata __attribute__((unused))) +{ + grub_printf (" Booting \'%s\'\n\n", entry->title); +} + +/* Callback invoked when a default menu entry executed because of a timeout + has failed and an attempt will be made to execute the next fallback + entry, ENTRY. */ +static void +notify_fallback (grub_menu_entry_t entry, + void *userdata __attribute__((unused))) +{ + grub_printf ("\n Falling back to \'%s\'\n\n", entry->title); + grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS); +} + +/* Callback invoked when a menu entry has failed and there is no remaining + fallback entry to attempt. */ +static void +notify_execution_failure (void *userdata __attribute__((unused))) +{ + if (grub_errno != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + grub_printf ("\n Failed to boot default entries.\n"); + grub_wait_after_message (); +} + +/* Callbacks used by the text menu to provide user feedback when menu entries + are executed. */ +static struct grub_menu_execute_callback execution_callback = +{ + .notify_booting = notify_booting, + .notify_fallback = notify_fallback, + .notify_failure = notify_execution_failure +}; + +static grub_err_t +show_text_menu (grub_menu_t menu, int nested) +{ + while (1) + { + int boot_entry; + grub_menu_entry_t e; + int auto_boot; + + boot_entry = run_menu (menu, nested, &auto_boot); + if (boot_entry < 0) + break; + + e = grub_menu_get_entry (menu, boot_entry); + if (! e) + continue; /* Menu is empty. */ + + grub_cls (); + grub_setcursor (1); + + if (auto_boot) + { + grub_menu_execute_with_fallback (menu, e, &execution_callback, 0); + } + else + { + grub_errno = GRUB_ERR_NONE; + grub_menu_execute_entry (e); + if (grub_errno != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_wait_after_message (); + } + } + } + + return GRUB_ERR_NONE; +} + +struct grub_menu_viewer grub_normal_text_menu_viewer = +{ + .name = "text", + .show_menu = show_text_menu +}; diff --git a/normal/menu_viewer.c b/normal/menu_viewer.c new file mode 100644 index 0000000..f7047c7 --- /dev/null +++ b/normal/menu_viewer.c @@ -0,0 +1,63 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +/* The list of menu viewers. */ +static grub_menu_viewer_t menu_viewer_list; + +void +grub_menu_viewer_register (grub_menu_viewer_t viewer) +{ + viewer->next = menu_viewer_list; + menu_viewer_list = viewer; +} + +static grub_menu_viewer_t get_current_menu_viewer (void) +{ + const char *selected_name = grub_env_get ("menuviewer"); + + /* If none selected, pick the last registered one. */ + if (selected_name == 0) + return menu_viewer_list; + + grub_menu_viewer_t cur; + for (cur = menu_viewer_list; cur; cur = cur->next) + { + if (grub_strcmp (cur->name, selected_name) == 0) + return cur; + } + + /* Fall back to the first entry (or null). */ + return menu_viewer_list; +} + +grub_err_t +grub_menu_viewer_show_menu (grub_menu_t menu, int nested) +{ + grub_menu_viewer_t cur = get_current_menu_viewer (); + if (!cur) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available."); + + return cur->show_menu (menu, nested); +} + diff --git a/normal/misc.c b/normal/misc.c new file mode 100644 index 0000000..e47ff87 --- /dev/null +++ b/normal/misc.c @@ -0,0 +1,89 @@ +/* misc.c - miscellaneous functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Print the information on the device NAME. */ +grub_err_t +grub_normal_print_device_info (const char *name) +{ + grub_device_t dev; + char *p; + + p = grub_strchr (name, ','); + if (p) + grub_printf ("\tPartition %s: ", name); + else + grub_printf ("Device %s: ", name); + + dev = grub_device_open (name); + if (! dev) + grub_printf ("Filesystem cannot be accessed"); + else if (dev->disk) + { + grub_fs_t fs; + + fs = grub_fs_probe (dev); + /* Ignore all errors. */ + grub_errno = 0; + + if (fs) + { + grub_printf ("Filesystem type %s", fs->name); + if (fs->label) + { + char *label; + (fs->label) (dev, &label); + if (grub_errno == GRUB_ERR_NONE) + { + if (label && grub_strlen (label)) + grub_printf (", Label %s", label); + grub_free (label); + } + grub_errno = GRUB_ERR_NONE; + } + if (fs->uuid) + { + char *uuid; + (fs->uuid) (dev, &uuid); + if (grub_errno == GRUB_ERR_NONE) + { + if (uuid && grub_strlen (uuid)) + grub_printf (", UUID %s", uuid); + grub_free (uuid); + } + grub_errno = GRUB_ERR_NONE; + } + } + else if (! dev->disk->has_partitions || dev->disk->partition) + grub_printf ("Unknown filesystem"); + else + grub_printf ("Partition table"); + + grub_device_close (dev); + } + + grub_printf ("\n"); + return grub_errno; +} diff --git a/normal/parser.y b/normal/parser.y new file mode 100644 index 0000000..eaf400b --- /dev/null +++ b/normal/parser.y @@ -0,0 +1,238 @@ +/* parser.y - The scripting parser. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +%{ +#include +#include + +#define YYFREE grub_free +#define YYMALLOC grub_malloc +#define YYLTYPE_IS_TRIVIAL 0 +#define YYENABLE_NLS 0 + +%} + +%union { + struct grub_script_cmd *cmd; + struct grub_script_arglist *arglist; + struct grub_script_arg *arg; + char *string; +} + +%token GRUB_PARSER_TOKEN_IF "if" +%token GRUB_PARSER_TOKEN_WHILE "while" +%token GRUB_PARSER_TOKEN_FUNCTION "function" +%token GRUB_PARSER_TOKEN_MENUENTRY "menuentry" +%token GRUB_PARSER_TOKEN_ELSE "else" +%token GRUB_PARSER_TOKEN_THEN "then" +%token GRUB_PARSER_TOKEN_FI "fi" +%token GRUB_PARSER_TOKEN_NAME +%token GRUB_PARSER_TOKEN_VAR +%type script_init script grubcmd command commands commandblock menuentry if +%type arguments; +%type argument; +%type "if" "while" "function" "else" "then" "fi" +%type text GRUB_PARSER_TOKEN_NAME GRUB_PARSER_TOKEN_VAR + +%pure-parser +%lex-param { struct grub_parser_param *state }; +%parse-param { struct grub_parser_param *state }; + +%% +/* It should be possible to do this in a clean way... */ +script_init: { state->err = 0; } script + { + state->parsed = $2; + } +; + +script: commands { $$ = $1; } + | function '\n' { $$ = 0; } + | menuentry '\n' { $$ = $1; } +; + +delimiter: '\n' + | ';' + | delimiter '\n' +; + +newlines: /* Empty */ + | newlines '\n' +; + +/* Some tokens are both used as token or as plain text. XXX: Add all + tokens without causing conflicts. */ +text: GRUB_PARSER_TOKEN_NAME + { + $$ = $1; + } + | "if" + { + $$ = $1; + } + | "while" + { + $$ = $1; + } +; + +/* An argument can consist of some static text mixed with variables, + for example: `foo${bar}baz'. */ +argument: GRUB_PARSER_TOKEN_VAR + { + $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_VAR, $1); + } + | text + { + $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_STR, $1); + } +/* XXX: Currently disabled to simplify the parser. This should be + parsed by yet another parser for readability. */ +/* | argument GRUB_PARSER_TOKEN_VAR */ +/* { */ +/* $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_VAR, $2); */ +/* } */ +/* | argument text */ +/* { */ +/* $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_STR, $2); */ +/* } */ +; + +arguments: argument + { + $$ = grub_script_add_arglist (state, 0, $1); + } + | arguments argument + { + $$ = grub_script_add_arglist (state, $1, $2); + } +; + +grubcmd: GRUB_PARSER_TOKEN_NAME arguments + { + $$ = grub_script_create_cmdline (state, $1, $2); + } + | GRUB_PARSER_TOKEN_NAME + { + $$ = grub_script_create_cmdline (state, $1, 0); + } +; + +/* A single command. */ +command: grubcmd delimiter { $$ = $1; } + | if delimiter { $$ = $1; } + | commandblock delimiter { $$ = $1; } + | error delimiter + { + $$ = 0; + yyerror (state, "Incorrect command"); + state->err = 1; + yyerrok; + } +; + +/* A block of commands. */ +commands: command + { + $$ = grub_script_add_cmd (state, 0, $1); + } + | command commands + { + struct grub_script_cmdblock *cmd; + cmd = (struct grub_script_cmdblock *) $2; + $$ = grub_script_add_cmd (state, cmd, $1); + } +; + +/* A function. Carefully save the memory that is allocated. Don't + change any stuff because it might seem like a fun thing to do! + Special care was take to make sure the mid-rule actions are + executed on the right moment. So the `commands' rule should be + recognized after executing the `grub_script_mem_record; and before + `grub_script_mem_record_stop'. */ +function: "function" GRUB_PARSER_TOKEN_NAME + { + grub_script_lexer_ref (state->lexerstate); + } newlines '{' + { + /* The first part of the function was recognized. + Now start recording the memory usage to store + this function. */ + state->func_mem = grub_script_mem_record (state); + } newlines commands '}' + { + struct grub_script *script; + + /* All the memory usage for parsing this function + was recorded. */ + state->func_mem = grub_script_mem_record_stop (state, + state->func_mem); + script = grub_script_create ($8, state->func_mem); + if (script) + grub_script_function_create ($2, script); + grub_script_lexer_deref (state->lexerstate); + } +; + +/* Carefully designed, together with `menuentry' so everything happens + just in the expected order. */ +commandblock: '{' + { + grub_script_lexer_ref (state->lexerstate); + } + newlines commands '}' + { + grub_script_lexer_deref (state->lexerstate); + $$ = $4; + } +; + +/* A menu entry. Carefully save the memory that is allocated. */ +menuentry: "menuentry" arguments + { + grub_script_lexer_ref (state->lexerstate); + } newlines '{' + { + grub_script_lexer_record_start (state->lexerstate); + } newlines commands '}' + { + char *menu_entry; + menu_entry = grub_script_lexer_record_stop (state->lexerstate); + grub_script_lexer_deref (state->lexerstate); + $$ = grub_script_create_cmdmenu (state, $2, menu_entry, 0); + } +; + +/* The first part of the if statement. It's used to switch the lexer + to a state in which it demands more tokens. */ +if_statement: "if" { grub_script_lexer_ref (state->lexerstate); } +; + +/* The if statement. */ +if: if_statement commands "then" newlines commands "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, 0); + grub_script_lexer_deref (state->lexerstate); + } + | if_statement commands "then" newlines commands "else" newlines commands "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, $8); + grub_script_lexer_deref (state->lexerstate); + } +; diff --git a/normal/powerpc/setjmp.S b/normal/powerpc/setjmp.S new file mode 100644 index 0000000..25cbaa3 --- /dev/null +++ b/normal/powerpc/setjmp.S @@ -0,0 +1,84 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "setjmp.S" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + stw 1, 0(3) + stw 14, 4(3) + stw 15, 8(3) + stw 16, 12(3) + stw 17, 16(3) + stw 18, 20(3) + stw 19, 24(3) + stw 20, 28(3) + stw 21, 32(3) + stw 22, 36(3) + stw 23, 40(3) + stw 24, 44(3) + stw 25, 48(3) + stw 26, 52(3) + stw 27, 56(3) + stw 28, 60(3) + stw 29, 64(3) + stw 30, 68(3) + mflr 4 + stw 4, 72(3) + mfcr 4 + stw 4, 76(3) + li 3, 0 + blr + +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + lwz 1, 0(3) + lwz 14, 4(3) + lwz 15, 8(3) + lwz 16, 12(3) + lwz 17, 16(3) + lwz 18, 20(3) + lwz 19, 24(3) + lwz 20, 28(3) + lwz 21, 32(3) + lwz 22, 36(3) + lwz 23, 40(3) + lwz 24, 44(3) + lwz 25, 48(3) + lwz 26, 52(3) + lwz 27, 56(3) + lwz 28, 60(3) + lwz 29, 64(3) + lwz 30, 68(3) + lwz 5, 72(3) + mtlr 5 + lwz 5, 76(3) + mtcr 5 + mr. 3, 4 + bne 1f + li 3, 1 +1: blr + diff --git a/normal/script.c b/normal/script.c new file mode 100644 index 0000000..0d5d5a8 --- /dev/null +++ b/normal/script.c @@ -0,0 +1,348 @@ +/* script.c -- Functions to create an in memory description of the script. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* It is not possible to deallocate the memory when a syntax error was + found. Because of that it is required to keep track of all memory + allocations. The memory is freed in case of an error, or + assigned to the parsed script when parsing was successful. */ + +/* XXX */ + +/* In case of the normal malloc, some additional bytes are allocated + for this datastructure. All reserved memory is stored in a linked + list so it can be easily freed. The original memory can be found + from &mem. */ +struct grub_script_mem +{ + struct grub_script_mem *next; + char mem; +}; + +/* Return malloc'ed memory and keep track of the allocation. */ +void * +grub_script_malloc (struct grub_parser_param *state, grub_size_t size) +{ + struct grub_script_mem *mem; + mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem) + - sizeof (char)); + + grub_dprintf ("scripting", "malloc %p\n", mem); + mem->next = state->memused; + state->memused = mem; + return (void *) &mem->mem; +} + +/* Free all memory described by MEM. */ +static void +grub_script_mem_free (struct grub_script_mem *mem) +{ + struct grub_script_mem *memfree; + + while (mem) + { + memfree = mem->next; + grub_dprintf ("scripting", "free %p\n", mem); + grub_free (mem); + mem = memfree; + } +} + +/* Start recording memory usage. Returns the memory that should be + restored when calling stop. */ +struct grub_script_mem * +grub_script_mem_record (struct grub_parser_param *state) +{ + struct grub_script_mem *mem = state->memused; + state->memused = 0; + + return mem; +} + +/* Stop recording memory usage. Restore previous recordings using + RESTORE. Return the recorded memory. */ +struct grub_script_mem * +grub_script_mem_record_stop (struct grub_parser_param *state, + struct grub_script_mem *restore) +{ + struct grub_script_mem *mem = state->memused; + state->memused = restore; + return mem; +} + +/* Free the memory reserved for CMD and all of it's children. */ +void +grub_script_free (struct grub_script *script) +{ + if (! script) + return; + grub_script_mem_free (script->mem); + grub_free (script); +} + + + +/* Extend the argument arg with a variable or string of text. If ARG + is zero a new list is created. */ +struct grub_script_arg * +grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg, + grub_script_arg_type_t type, char *str) +{ + struct grub_script_arg *argpart; + struct grub_script_arg *ll; + + argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg)); + argpart->type = type; + argpart->str = str; + argpart->next = 0; + + if (! arg) + return argpart; + + for (ll = arg; ll->next; ll = ll->next); + ll->next = argpart; + + return arg; +} + +/* Add the argument ARG to the end of the argument list LIST. If LIST + is zero, a new list will be created. */ +struct grub_script_arglist * +grub_script_add_arglist (struct grub_parser_param *state, + struct grub_script_arglist *list, struct grub_script_arg *arg) +{ + struct grub_script_arglist *link; + struct grub_script_arglist *ll; + + grub_dprintf ("scripting", "arglist\n"); + + link = (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link)); + link->next = 0; + link->arg = arg; + link->argcount = 0; + + if (! list) + { + link->argcount++; + return link; + } + + list->argcount++; + + /* Look up the last link in the chain. */ + for (ll = list; ll->next; ll = ll->next); + ll->next = link; + + return list; +} + +/* Create a command that describes a single command line. CMDLINE + contains the name of the command that should be executed. ARGLIST + holds all arguments for this command. */ +struct grub_script_cmd * +grub_script_create_cmdline (struct grub_parser_param *state, + char *cmdname, struct grub_script_arglist *arglist) +{ + struct grub_script_cmdline *cmd; + + grub_dprintf ("scripting", "cmdline\n"); + + cmd = grub_script_malloc (state, sizeof (*cmd)); + cmd->cmd.exec = grub_script_execute_cmdline; + cmd->cmd.next = 0; + cmd->arglist = arglist; + cmd->cmdname = cmdname; + + return (struct grub_script_cmd *) cmd; +} + +/* Create a command that functions as an if statement. If BOOL is + evaluated to true (the value is returned in envvar '?'), the + interpreter will run the command TRUE, otherwise the interpreter + runs the command FALSE. */ +struct grub_script_cmd * +grub_script_create_cmdif (struct grub_parser_param *state, + struct grub_script_cmd *exec_to_evaluate, + struct grub_script_cmd *exec_on_true, + struct grub_script_cmd *exec_on_false) +{ + struct grub_script_cmdif *cmd; + + grub_dprintf ("scripting", "cmdif\n"); + + cmd = grub_script_malloc (state, sizeof (*cmd)); + cmd->cmd.exec = grub_script_execute_cmdif; + cmd->cmd.next = 0; + cmd->exec_to_evaluate = exec_to_evaluate; + cmd->exec_on_true = exec_on_true; + cmd->exec_on_false = exec_on_false; + + return (struct grub_script_cmd *) cmd; +} + +/* Create a command that adds a menu entry to the menu. Title is an + argument that is parsed to generate a string that can be used as + the title. The sourcecode for this entry is passed in SOURCECODE. + The options for this entry are passed in OPTIONS. */ +struct grub_script_cmd * +grub_script_create_cmdmenu (struct grub_parser_param *state, + struct grub_script_arglist *arglist, + char *sourcecode, + int options) +{ + struct grub_script_cmd_menuentry *cmd; + int i; + + /* Skip leading newlines to make the sourcecode better readable when + using the editor. */ + while (*sourcecode == '\n') + sourcecode++; + + /* Having trailing returns can some some annoying conflicts, remove + them. XXX: Can the parser be improved to handle this? */ + for (i = grub_strlen (sourcecode) - 1; i > 0; i--) + { + if (sourcecode[i] != '\n') + break; + sourcecode[i] = '\0'; + } + + cmd = grub_script_malloc (state, sizeof (*cmd)); + cmd->cmd.exec = grub_script_execute_menuentry; + cmd->cmd.next = 0; + /* XXX: Check if this memory is properly freed. */ + cmd->sourcecode = sourcecode; + cmd->arglist = arglist; + cmd->options = options; + + return (struct grub_script_cmd *) cmd; +} + +/* Create a block of commands. CMD contains the command that should + be added at the end of CMDBLOCK's list. If CMDBLOCK is zero, a new + cmdblock will be created. */ +struct grub_script_cmd * +grub_script_add_cmd (struct grub_parser_param *state, + struct grub_script_cmdblock *cmdblock, + struct grub_script_cmd *cmd) +{ + grub_dprintf ("scripting", "cmdblock\n"); + + if (! cmd) + return (struct grub_script_cmd *) cmdblock; + + if (! cmdblock) + { + cmdblock = (struct grub_script_cmdblock *) grub_script_malloc (state, + sizeof (*cmdblock)); + cmdblock->cmd.exec = grub_script_execute_cmdblock; + cmdblock->cmd.next = 0; + cmdblock->cmdlist = cmd; + cmd->next = 0; + } + else + { + cmd->next = cmdblock->cmdlist; + cmdblock->cmdlist = cmd; + } + + return (struct grub_script_cmd *) cmdblock; +} + + + +struct grub_script * +grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem) +{ + struct grub_script *parsed; + + parsed = grub_malloc (sizeof (*parsed)); + if (! parsed) + { + grub_script_mem_free (mem); + grub_free (cmd); + + return 0; + } + + parsed->mem = mem; + parsed->cmd = cmd; + + return parsed; +} + +/* Parse the script passed in SCRIPT and return the parsed + datastructure that is ready to be interpreted. */ +struct grub_script * +grub_script_parse (char *script, grub_err_t (*getline) (char **)) +{ + struct grub_script *parsed; + struct grub_script_mem *membackup; + struct grub_lexer_param *lexstate; + struct grub_parser_param *parsestate; + + parsed = grub_malloc (sizeof (*parsed)); + if (! parsed) + return 0; + + parsestate = grub_malloc (sizeof (*parsestate)); + if (! parsestate) + return 0; + + parsestate->err = 0; + parsestate->func_mem = 0; + parsestate->memused = 0; + parsestate->parsed = 0; + + /* Initialize the lexer. */ + lexstate = grub_script_lexer_init (script, getline); + if (! lexstate) + { + grub_free (parsed); + grub_free (parsestate); + return 0; + } + + parsestate->lexerstate = lexstate; + + membackup = grub_script_mem_record (parsestate); + + /* Parse the script. */ + if (grub_script_yyparse (parsestate) || parsestate->err) + { + struct grub_script_mem *memfree; + memfree = grub_script_mem_record_stop (parsestate, membackup); + grub_script_mem_free (memfree); + grub_free (lexstate); + grub_free (parsestate); + return 0; + } + + parsed->mem = grub_script_mem_record_stop (parsestate, membackup); + parsed->cmd = parsestate->parsed; + + grub_free (lexstate); + grub_free (parsestate); + + return parsed; +} diff --git a/normal/sparc64/setjmp.S b/normal/sparc64/setjmp.S new file mode 100644 index 0000000..b1a9b6e --- /dev/null +++ b/normal/sparc64/setjmp.S @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "setjmp.S" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + ret + nop + +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + ret + nop + diff --git a/normal/x86_64/setjmp.S b/normal/x86_64/setjmp.S new file mode 100644 index 0000000..621b09b --- /dev/null +++ b/normal/x86_64/setjmp.S @@ -0,0 +1,65 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "setjmp.S" + + .text + +/* + * jmp_buf: + * rbx rsp rbp r12 r13 r14 r15 rip + * 0 8 16 24 32 40 48 56 + */ + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + pop %rsi /* Return address, and adjust the stack */ + xorq %rax, %rax + movq %rbx, 0(%rdi) /* RBX */ + movq %rsp, 8(%rdi) /* RSP */ + push %rsi + movq %rbp, 16(%rdi) /* RBP */ + movq %r12, 24(%rdi) /* R12 */ + movq %r13, 32(%rdi) /* R13 */ + movq %r14, 40(%rdi) /* R14 */ + movq %r15, 48(%rdi) /* R15 */ + movq %rsi, 56(%rdi) /* RSI */ + ret + +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + movl %esi, %eax + orl %eax, %eax + jnz 1f + incl %eax +1: + + movq (%rdi), %rbx + movq 8(%rdi), %rsp + movq 16(%rdi), %rbp + movq 24(%rdi), %r12 + movq 32(%rdi), %r13 + movq 40(%rdi), %r14 + movq 48(%rdi), %r15 + jmp *56(%rdi) diff --git a/partmap/acorn.c b/partmap/acorn.c new file mode 100644 index 0000000..9db5e0e --- /dev/null +++ b/partmap/acorn.c @@ -0,0 +1,206 @@ +/* acorn.c - Read Linux/ADFS partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#define LINUX_NATIVE_MAGIC grub_cpu_to_le32 (0xdeafa1de) +#define LINUX_SWAP_MAGIC grub_cpu_to_le32 (0xdeafab1e) +#define LINUX_MAP_ENTRIES (512 / 12) + +#define NONADFS_PARTITION_TYPE_LINUX 9 +#define NONADFS_PARTITION_TYPE_MASK 15 + +struct grub_acorn_boot_block +{ + grub_uint8_t misc[0x1C0]; + struct grub_filecore_disc_record disc_record; + grub_uint8_t flags; + grub_uint16_t start_cylinder; + grub_uint8_t checksum; +} __attribute__ ((packed, aligned)); + +struct linux_part +{ + grub_uint32_t magic; + grub_uint32_t start; + grub_uint32_t size; +}; + +static struct grub_partition_map grub_acorn_partition_map; + +static grub_err_t +acorn_partition_map_find (grub_disk_t disk, struct linux_part *m, + grub_disk_addr_t *sector) +{ + struct grub_acorn_boot_block boot; + grub_err_t err; + unsigned int checksum = 0; + unsigned int heads; + unsigned int sectors_per_cylinder; + int i; + + err = grub_disk_read (disk, 0xC00 / GRUB_DISK_SECTOR_SIZE, 0, + sizeof (struct grub_acorn_boot_block), + (char *) &boot); + if (err) + return err; + + if ((boot.flags & NONADFS_PARTITION_TYPE_MASK) != NONADFS_PARTITION_TYPE_LINUX) + goto fail; + + for (i = 0; i != 0x1ff; ++i) + checksum = (checksum & 0xff) + (checksum >> 8) + boot.misc[i]; + + if ((grub_uint8_t) checksum != boot.checksum) + goto fail; + + heads = (boot.disc_record.heads + + ((boot.disc_record.lowsector >> 6) & 1)); + sectors_per_cylinder = boot.disc_record.secspertrack * heads; + *sector = grub_le_to_cpu16 (boot.start_cylinder) * sectors_per_cylinder; + + return grub_disk_read (disk, *sector, 0, + sizeof (struct linux_part) * LINUX_MAP_ENTRIES, + (char *) m); + +fail: + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "Linux/ADFS partition map not found."); + +} + + +static grub_err_t +acorn_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition part; + struct grub_disk raw; + struct linux_part map[LINUX_MAP_ENTRIES]; + int i; + grub_disk_addr_t sector; + grub_err_t err; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + err = acorn_partition_map_find (&raw, map, §or); + if (err) + return err; + + part.partmap = &grub_acorn_partition_map; + + for (i = 0; i != LINUX_MAP_ENTRIES; ++i) + { + if (map[i].magic != LINUX_NATIVE_MAGIC + && map[i].magic != LINUX_SWAP_MAGIC) + return GRUB_ERR_NONE; + + part.start = sector + map[i].start; + part.len = map[i].size; + part.offset = 6; + part.index = i; + + if (hook (disk, &part)) + return grub_errno; + } + + return GRUB_ERR_NONE; +} + + +static grub_partition_t +acorn_partition_map_probe (grub_disk_t disk, const char *str) +{ + struct linux_part map[LINUX_MAP_ENTRIES]; + struct grub_disk raw = *disk; + unsigned long partnum = grub_strtoul (str, 0, 10) - 1; + grub_disk_addr_t sector; + grub_err_t err; + grub_partition_t p; + + /* Enforce raw disk access. */ + raw.partition = 0; + + /* Get the partition number. */ + if (partnum > LINUX_MAP_ENTRIES) + goto fail; + + err = acorn_partition_map_find (&raw, map, §or); + if (err) + return 0; + + if (map[partnum].magic != LINUX_NATIVE_MAGIC + && map[partnum].magic != LINUX_SWAP_MAGIC) + goto fail; + + p = grub_malloc (sizeof (struct grub_partition)); + if (! p) + return 0; + + p->start = sector + map[partnum].start; + p->len = map[partnum].size; + p->offset = 6; + p->index = partnum; + return p; + +fail: + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + return 0; +} + + +static char * +acorn_partition_map_get_name (const grub_partition_t p) +{ + char *name; + + name = grub_malloc (13); + if (! name) + return 0; + + grub_sprintf (name, "%d", p->index + 1); + return name; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_acorn_partition_map = +{ + .name = "Linux/ADFS partition map", + .iterate = acorn_partition_map_iterate, + .probe = acorn_partition_map_probe, + .get_name = acorn_partition_map_get_name +}; + +GRUB_MOD_INIT(acorn_partition_map) +{ + grub_partition_map_register (&grub_acorn_partition_map); +} + +GRUB_MOD_FINI(acorn_partition_map) +{ + grub_partition_map_unregister (&grub_acorn_partition_map); +} diff --git a/partmap/amiga.c b/partmap/amiga.c new file mode 100644 index 0000000..fde3011 --- /dev/null +++ b/partmap/amiga.c @@ -0,0 +1,222 @@ +/* amiga.c - Read amiga partition tables (RDB). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +struct grub_amiga_rdsk +{ + /* "RDSK". */ + grub_uint8_t magic[4]; + grub_uint32_t size; + grub_int32_t checksum; + grub_uint32_t scsihost; + grub_uint32_t blksz; + grub_uint32_t flags; + grub_uint32_t badblcklst; + grub_uint32_t partitionlst; + grub_uint32_t fslst; + + /* The other information is not important for us. */ +} __attribute__ ((packed)); + +struct grub_amiga_partition +{ + /* "PART". */ + grub_uint8_t magic[4]; + grub_int32_t size; + grub_int32_t checksum; + grub_uint32_t scsihost; + grub_uint32_t next; + grub_uint32_t flags; + grub_uint32_t unused1[2]; + grub_uint32_t devflags; + grub_uint8_t namelen; + grub_uint8_t name[31]; + grub_uint32_t unused2[15]; + + grub_uint32_t unused3[3]; + grub_uint32_t heads; + grub_uint32_t unused4; + grub_uint32_t block_per_track; + grub_uint32_t unused5[3]; + grub_uint32_t lowcyl; + grub_uint32_t highcyl; + + grub_uint32_t firstcyl; +} __attribute__ ((packed)); + +static struct grub_partition_map grub_amiga_partition_map; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + + +static grub_err_t +amiga_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition part; + struct grub_amiga_rdsk rdsk; + struct grub_disk raw; + int partno = 0; + int next = -1; + unsigned pos; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + /* The RDSK block is one of the first 15 blocks. */ + for (pos = 0; pos < 15; pos++) + { + /* Read the RDSK block which is a descriptor for the entire disk. */ + if (grub_disk_read (&raw, pos, 0, sizeof (rdsk), (char *) &rdsk)) + return grub_errno; + + if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0) + { + /* Found the first PART block. */ + next = grub_be_to_cpu32 (rdsk.partitionlst); + break; + } + } + + if (next == -1) + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "Amiga partition map not found."); + + /* The end of the partition list is marked using "-1". */ + while (next != -1) + { + struct grub_amiga_partition apart; + + /* Read the RDSK block which is a descriptor for the entire disk. */ + if (grub_disk_read (&raw, next, 0, sizeof (apart), (char *) &apart)) + return grub_errno; + + /* Calculate the first block and the size of the partition. */ + part.start = (grub_be_to_cpu32 (apart.lowcyl) + * grub_be_to_cpu32 (apart.heads) + * grub_be_to_cpu32 (apart.block_per_track)); + part.len = ((grub_be_to_cpu32 (apart.highcyl) + - grub_be_to_cpu32 (apart.lowcyl) + 1) + * grub_be_to_cpu32 (apart.heads) + * grub_be_to_cpu32 (apart.block_per_track)); + + part.offset = (grub_off_t) next * 512; + part.index = partno; + part.partmap = &grub_amiga_partition_map; + + if (hook (disk, &part)) + return grub_errno; + + next = grub_be_to_cpu32 (apart.next); + partno++; + } + + return 0; +} + + +static grub_partition_t +amiga_partition_map_probe (grub_disk_t disk, const char *str) +{ + grub_partition_t p = 0; + int partnum = 0; + char *s = (char *) str; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + if (partnum == partition->index) + { + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 1; + + grub_memcpy (p, partition, sizeof (*p)); + return 1; + } + + return 0; + } + + /* Get the partition number. */ + partnum = grub_strtoul (s, 0, 10) - 1; + if (grub_errno) + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + return 0; + } + + if (amiga_partition_map_iterate (disk, find_func)) + goto fail; + + return p; + + fail: + grub_free (p); + return 0; +} + + +static char * +amiga_partition_map_get_name (const grub_partition_t p) +{ + char *name; + + name = grub_malloc (13); + if (! name) + return 0; + + grub_sprintf (name, "%d", p->index + 1); + return name; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_amiga_partition_map = + { + .name = "amiga_partition_map", + .iterate = amiga_partition_map_iterate, + .probe = amiga_partition_map_probe, + .get_name = amiga_partition_map_get_name + }; + +GRUB_MOD_INIT(amiga_partition_map) +{ + grub_partition_map_register (&grub_amiga_partition_map); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(amiga_partition_map) +{ + grub_partition_map_unregister (&grub_amiga_partition_map); +} diff --git a/partmap/apple.c b/partmap/apple.c new file mode 100644 index 0000000..d6ddc0b --- /dev/null +++ b/partmap/apple.c @@ -0,0 +1,259 @@ +/* apple.c - Read macintosh partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +#define GRUB_APPLE_HEADER_MAGIC 0x4552 +#define GRUB_APPLE_PART_MAGIC 0x504D + +struct grub_apple_header +{ + /* The magic number to identify the partition map, it should have + the value `0x4552'. */ + grub_uint16_t magic; +}; + +struct grub_apple_part +{ + /* The magic number to identify this as a partition, it should have + the value `0x504D'. */ + grub_uint16_t magic; + + /* Reserved. */ + grub_uint16_t reserved; + + /* The size of the partition map in blocks. */ + grub_uint32_t partmap_size; + + /* The first physical block of the partition. */ + grub_uint32_t first_phys_block; + + /* The amount of blocks. */ + grub_uint32_t blockcnt; + + /* The partition name. */ + char partname[32]; + + /* The partition type. */ + char parttype[32]; + + /* The first datablock of the partition. */ + grub_uint32_t datablocks_first; + + /* The amount datablocks. */ + grub_uint32_t datablocks_count; + + /* The status of the partition. (???) */ + grub_uint32_t status; + + /* The first block on which the bootcode can be found. */ + grub_uint32_t bootcode_pos; + + /* The size of the bootcode in bytes. */ + grub_uint32_t bootcode_size; + + /* The load address of the bootcode. */ + grub_uint32_t bootcode_loadaddr; + + /* Reserved. */ + grub_uint32_t reserved2; + + /* The entrypoint of the bootcode. */ + grub_uint32_t bootcode_entrypoint; + + /* Reserved. */ + grub_uint32_t reserved3; + + /* A checksum of the bootcode. */ + grub_uint32_t bootcode_checksum; + + /* The processor type. */ + char processor[16]; + + /* Padding. */ + grub_uint16_t pad[187]; +}; + +static struct grub_partition_map grub_apple_partition_map; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +static grub_err_t +apple_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition part; + struct grub_apple_header aheader; + struct grub_apple_part apart; + struct grub_disk raw; + int partno = 0; + unsigned pos = GRUB_DISK_SECTOR_SIZE; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + part.partmap = &grub_apple_partition_map; + + if (grub_disk_read (&raw, 0, 0, sizeof (aheader), (char *) &aheader)) + return grub_errno; + + if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC) + { + grub_dprintf ("partition", + "bad magic (found 0x%x; wanted 0x%x\n", + grub_be_to_cpu16 (aheader.magic), + GRUB_APPLE_HEADER_MAGIC); + goto fail; + } + + for (;;) + { + if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE, + pos % GRUB_DISK_SECTOR_SIZE, + sizeof (struct grub_apple_part), (char *) &apart)) + return grub_errno; + + if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC) + { + grub_dprintf ("partition", + "partition %d: bad magic (found 0x%x; wanted 0x%x\n", + partno, grub_be_to_cpu16 (apart.magic), + GRUB_APPLE_PART_MAGIC); + break; + } + + part.start = grub_be_to_cpu32 (apart.first_phys_block); + part.len = grub_be_to_cpu32 (apart.blockcnt); + part.offset = pos; + part.index = partno; + + grub_dprintf ("partition", + "partition %d: name %s, type %s, start 0x%x, len 0x%x\n", + partno, apart.partname, apart.parttype, + grub_be_to_cpu32 (apart.first_phys_block), + grub_be_to_cpu32 (apart.blockcnt)); + + if (hook (disk, &part)) + return grub_errno; + + if (grub_be_to_cpu32 (apart.first_phys_block) + == GRUB_DISK_SECTOR_SIZE * 2) + return 0; + + pos += sizeof (struct grub_apple_part); + partno++; + } + + if (pos != GRUB_DISK_SECTOR_SIZE) + return 0; + + fail: + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "Apple partition map not found."); +} + + +static grub_partition_t +apple_partition_map_probe (grub_disk_t disk, const char *str) +{ + grub_partition_t p = 0; + int partnum = 0; + char *s = (char *) str; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + if (partnum == partition->index) + { + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 1; + + grub_memcpy (p, partition, sizeof (*p)); + return 1; + } + + return 0; + } + + /* Get the partition number. */ + partnum = grub_strtoul (s, 0, 10) - 1; + if (grub_errno) + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + return 0; + } + + if (apple_partition_map_iterate (disk, find_func)) + goto fail; + + return p; + + fail: + grub_free (p); + return 0; +} + + +static char * +apple_partition_map_get_name (const grub_partition_t p) +{ + char *name; + + name = grub_malloc (13); + if (! name) + return 0; + + grub_sprintf (name, "%d", p->index + 1); + return name; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_apple_partition_map = + { + .name = "apple_partition_map", + .iterate = apple_partition_map_iterate, + .probe = apple_partition_map_probe, + .get_name = apple_partition_map_get_name + }; + +GRUB_MOD_INIT(apple_partition_map) +{ + grub_partition_map_register (&grub_apple_partition_map); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(apple_partition_map) +{ + grub_partition_map_unregister (&grub_apple_partition_map); +} + diff --git a/partmap/gpt.c b/partmap/gpt.c new file mode 100644 index 0000000..683fcba --- /dev/null +++ b/partmap/gpt.c @@ -0,0 +1,200 @@ +/* gpt.c - Read GUID Partition Tables (GPT). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_uint8_t grub_gpt_magic[8] = + { + 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 + }; + +static const grub_gpt_part_type_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; + +static struct grub_partition_map grub_gpt_partition_map; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + + +static grub_err_t +gpt_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition part; + struct grub_gpt_header gpt; + struct grub_gpt_partentry entry; + struct grub_disk raw; + struct grub_pc_partition_mbr mbr; + grub_uint64_t entries; + unsigned int i; + int last_offset = 0; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + /* Read the protective MBR. */ + if (grub_disk_read (&raw, 0, 0, sizeof (mbr), (char *) &mbr)) + return grub_errno; + + /* Check if it is valid. */ + if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + + /* Make sure the MBR is a protective MBR and not a normal MBR. */ + if (mbr.entries[0].type != GRUB_PC_PARTITION_TYPE_GPT_DISK) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); + + /* Read the GPT header. */ + if (grub_disk_read (&raw, 1, 0, sizeof (gpt), (char *) &gpt)) + return grub_errno; + + if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic))) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header"); + + grub_dprintf ("gpt", "Read a valid GPT header\n"); + + entries = grub_le_to_cpu64 (gpt.partitions); + for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++) + { + if (grub_disk_read (&raw, entries, last_offset, + sizeof (entry), (char *) &entry)) + return grub_errno; + + if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type, + sizeof (grub_gpt_partition_type_empty))) + { + /* Calculate the first block and the size of the partition. */ + part.start = grub_le_to_cpu64 (entry.start); + part.len = (grub_le_to_cpu64 (entry.end) + - grub_le_to_cpu64 (entry.start) + 1); + part.offset = entries; + part.index = i; + part.partmap = &grub_gpt_partition_map; + part.data = &entry; + + grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i, + (unsigned long long) part.start, + (unsigned long long) part.len); + + if (hook (disk, &part)) + return 1; + } + + last_offset += grub_le_to_cpu32 (gpt.partentry_size); + if (last_offset == GRUB_DISK_SECTOR_SIZE) + { + last_offset = 0; + entries++; + } + } + + return 0; +} + + +static grub_partition_t +gpt_partition_map_probe (grub_disk_t disk, const char *str) +{ + grub_partition_t p = 0; + int partnum = 0; + char *s = (char *) str; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + if (partnum == partition->index) + { + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 1; + + grub_memcpy (p, partition, sizeof (*p)); + return 1; + } + + return 0; + } + + /* Get the partition number. */ + partnum = grub_strtoul (s, 0, 10) - 1; + if (grub_errno) + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + return 0; + } + + gpt_partition_map_iterate (disk, find_func); + if (grub_errno) + goto fail; + + return p; + + fail: + grub_free (p); + return 0; +} + + +static char * +gpt_partition_map_get_name (const grub_partition_t p) +{ + char *name; + + name = grub_malloc (13); + if (! name) + return 0; + + grub_sprintf (name, "%d", p->index + 1); + return name; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_gpt_partition_map = + { + .name = "gpt_partition_map", + .iterate = gpt_partition_map_iterate, + .probe = gpt_partition_map_probe, + .get_name = gpt_partition_map_get_name + }; + +GRUB_MOD_INIT(gpt_partition_map) +{ + grub_partition_map_register (&grub_gpt_partition_map); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(gpt_partition_map) +{ + grub_partition_map_unregister (&grub_gpt_partition_map); +} diff --git a/partmap/pc.c b/partmap/pc.c new file mode 100644 index 0000000..419775a --- /dev/null +++ b/partmap/pc.c @@ -0,0 +1,320 @@ +/* pc.c - Read PC style partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static struct grub_partition_map grub_pc_partition_map; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + + +/* Parse the partition representation in STR and return a partition. */ +static grub_partition_t +grub_partition_parse (const char *str) +{ + grub_partition_t p; + struct grub_pc_partition *pcdata; + + char *s = (char *) str; + + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 0; + + pcdata = (struct grub_pc_partition *) grub_malloc (sizeof (*pcdata)); + if (! pcdata) + goto fail; + + p->data = pcdata; + p->partmap = &grub_pc_partition_map; + + /* Initialize some of the fields with invalid values. */ + pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1; + + /* Get the DOS partition number. The number is counted from one for + the user interface, and from zero internally. */ + pcdata->dos_part = grub_strtoul (s, &s, 0) - 1; + + if (grub_errno) + { + /* Not found. Maybe only a BSD label is specified. */ + pcdata->dos_part = -1; + grub_errno = GRUB_ERR_NONE; + } + else if (*s == ',') + s++; + + if (*s) + { + if (*s >= 'a' && *s <= 'h') + { + pcdata->bsd_part = *s - 'a'; + s++; + } + + if (*s) + goto fail; + } + + if (pcdata->dos_part == -1 && pcdata->bsd_part == -1) + goto fail; + + return p; + + fail: + grub_free (p); + grub_free (pcdata); + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + return 0; +} + +static grub_err_t +pc_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition p; + struct grub_pc_partition pcdata; + struct grub_pc_partition_mbr mbr; + struct grub_pc_partition_disk_label label; + struct grub_disk raw; + + /* Enforce raw disk access. */ + raw = *disk; + raw.partition = 0; + + p.offset = 0; + pcdata.ext_offset = 0; + pcdata.dos_part = -1; + p.data = &pcdata; + p.partmap = &grub_pc_partition_map; + + while (1) + { + int i; + struct grub_pc_partition_entry *e; + + /* Read the MBR. */ + if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), (char *) &mbr)) + goto finish; + + /* Check if it is valid. */ + if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + + /* Analyze DOS partitions. */ + for (p.index = 0; p.index < 4; p.index++) + { + e = mbr.entries + p.index; + + p.start = p.offset + grub_le_to_cpu32 (e->start); + p.len = grub_le_to_cpu32 (e->length); + pcdata.bsd_part = -1; + pcdata.dos_type = e->type; + pcdata.bsd_type = -1; + + grub_dprintf ("partition", + "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n", + p.index, e->flag, pcdata.dos_type, + (unsigned long long) p.start, + (unsigned long long) p.len); + + /* If this is a GPT partition, this MBR is just a dummy. */ + if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr"); + + /* If this partition is a normal one, call the hook. */ + if (! grub_pc_partition_is_empty (e->type) + && ! grub_pc_partition_is_extended (e->type)) + { + pcdata.dos_part++; + + if (hook (disk, &p)) + return 1; + + /* Check if this is a BSD partition. */ + if (grub_pc_partition_is_bsd (e->type)) + { + /* Check if the BSD label is within the DOS partition. */ + if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR) + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "no space for disk label"); + + /* Read the BSD label. */ + if (grub_disk_read (&raw, + (p.start + + GRUB_PC_PARTITION_BSD_LABEL_SECTOR), + 0, + sizeof (label), + (char *) &label)) + goto finish; + + /* Check if it is valid. */ + if (label.magic + != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "invalid disk label magic 0x%x", + label.magic); + + for (pcdata.bsd_part = 0; + pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions); + pcdata.bsd_part++) + { + struct grub_pc_partition_bsd_entry *be + = label.entries + pcdata.bsd_part; + + p.start = grub_le_to_cpu32 (be->offset); + p.len = grub_le_to_cpu32 (be->size); + pcdata.bsd_type = be->fs_type; + + if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + if (hook (disk, &p)) + return 1; + } + } + } + else if (pcdata.dos_part < 4) + /* If this partition is a logical one, shouldn't increase the + partition number. */ + pcdata.dos_part++; + } + + /* Find an extended partition. */ + for (i = 0; i < 4; i++) + { + e = mbr.entries + i; + + if (grub_pc_partition_is_extended (e->type)) + { + p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start); + if (! pcdata.ext_offset) + pcdata.ext_offset = p.offset; + + break; + } + } + + /* If no extended partition, the end. */ + if (i == 4) + break; + } + + finish: + return grub_errno; +} + + +static grub_partition_t +pc_partition_map_probe (grub_disk_t disk, const char *str) +{ + grub_partition_t p; + struct grub_pc_partition *pcdata; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + struct grub_pc_partition *partdata = partition->data; + + if ((pcdata->dos_part == partdata->dos_part || pcdata->dos_part == -1) + && pcdata->bsd_part == partdata->bsd_part) + { + grub_memcpy (p, partition, sizeof (*p)); + p->data = pcdata; + grub_memcpy (pcdata, partdata, sizeof (*pcdata)); + return 1; + } + + return 0; + } + + p = grub_partition_parse (str); + if (! p) + return 0; + + pcdata = p->data; + pc_partition_map_iterate (disk, find_func); + if (grub_errno) + goto fail; + + if (p->index < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "no such partition"); + goto fail; + } + + return p; + + fail: + grub_free (p); + grub_free (pcdata); + return 0; +} + + +static char * +pc_partition_map_get_name (const grub_partition_t p) +{ + char *name; + struct grub_pc_partition *pcdata = p->data; + + name = grub_malloc (13); + if (! name) + return 0; + + if (pcdata->bsd_part < 0) + grub_sprintf (name, "%d", pcdata->dos_part + 1); + else if (pcdata->dos_part < 0) + grub_sprintf (name, "%c", pcdata->bsd_part + 'a'); + else + grub_sprintf (name, "%d,%c", pcdata->dos_part + 1, pcdata->bsd_part + 'a'); + + return name; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_pc_partition_map = + { + .name = "pc_partition_map", + .iterate = pc_partition_map_iterate, + .probe = pc_partition_map_probe, + .get_name = pc_partition_map_get_name + }; + +GRUB_MOD_INIT(pc_partition_map) +{ + grub_partition_map_register (&grub_pc_partition_map); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(pc_partition_map) +{ + grub_partition_map_unregister (&grub_pc_partition_map); +} diff --git a/partmap/sun.c b/partmap/sun.c new file mode 100644 index 0000000..b05a2e2 --- /dev/null +++ b/partmap/sun.c @@ -0,0 +1,223 @@ +/* sun.c - Read SUN style partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_PARTMAP_SUN_MAGIC 0xDABE +#define GRUB_PARTMAP_SUN_MAX_PARTS 8 +#define GRUB_PARTMAP_SUN_WHOLE_DISK_ID 0x05 + +struct grub_sun_partition_info +{ + grub_uint8_t spare1; + grub_uint8_t id; + grub_uint8_t spare2; + grub_uint8_t flags; +} __attribute__ ((packed)); + +struct grub_sun_partition_descriptor +{ + grub_uint32_t start_cylinder; + grub_uint32_t num_sectors; +} __attribute__ ((packed)); + +struct grub_sun_block +{ + grub_uint8_t info[128]; /* Informative text string. */ + grub_uint8_t spare0[14]; + struct grub_sun_partition_info infos[8]; + grub_uint8_t spare1[246]; /* Boot information etc. */ + grub_uint16_t rspeed; /* Disk rotational speed. */ + grub_uint16_t pcylcount; /* Physical cylinder count. */ + grub_uint16_t sparecyl; /* extra sects per cylinder. */ + grub_uint8_t spare2[4]; /* More magic... */ + grub_uint16_t ilfact; /* Interleave factor. */ + grub_uint16_t ncyl; /* Data cylinder count. */ + grub_uint16_t nacyl; /* Alt. cylinder count. */ + grub_uint16_t ntrks; /* Tracks per cylinder. */ + grub_uint16_t nsect; /* Sectors per track. */ + grub_uint8_t spare3[4]; /* Even more magic... */ + struct grub_sun_partition_descriptor partitions[8]; + grub_uint16_t magic; /* Magic number. */ + grub_uint16_t csum; /* Label xor'd checksum. */ +} __attribute__ ((packed)); + +static struct grub_partition_map grub_sun_partition_map; + +#ifndef GRUB_UTIL +static grub_dl_t my_mod; +#endif + +/* Verify checksum (true=ok). */ +static int +grub_sun_is_valid (struct grub_sun_block *label) +{ + grub_uint16_t *pos; + grub_uint16_t sum = 0; + + for (pos = (grub_uint16_t *) label; + pos < (grub_uint16_t *) (label + 1); + pos++) + sum ^= *pos; + + return ! sum; +} + +static grub_err_t +sun_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + grub_partition_t p; + struct grub_disk raw; + struct grub_sun_block block; + int partnum; + + raw = *disk; + raw.partition = 0; + + p = (grub_partition_t) grub_malloc (sizeof (struct grub_partition)); + if (! p) + return grub_errno; + + p->offset = 0; + p->data = 0; + p->partmap = &grub_sun_partition_map; + if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block), + (char *) &block) == GRUB_ERR_NONE) + { + if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic)) + grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table"); + + if (! grub_sun_is_valid (&block)) + grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); + + /* Maybe another error value would be better, because partition + table _is_ recognized but invalid. */ + for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++) + { + struct grub_sun_partition_descriptor *desc; + + if (block.infos[partnum].id == 0 + || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID) + continue; + + desc = &block.partitions[partnum]; + p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder) + * grub_be_to_cpu16 (block.ntrks) + * grub_be_to_cpu16 (block.nsect)); + p->len = grub_be_to_cpu32 (desc->num_sectors); + p->index = partnum; + if (p->len) + { + if (hook (disk, p)) + partnum = GRUB_PARTMAP_SUN_MAX_PARTS; + } + } + } + + grub_free (p); + + return grub_errno; +} + +static grub_partition_t +sun_partition_map_probe (grub_disk_t disk, const char *str) +{ + grub_partition_t p = 0; + int partnum = 0; + char *s = (char *) str; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + if (partnum == partition->index) + { + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (p) + grub_memcpy (p, partition, sizeof (*p)); + + return 1; + } + + return 0; + } + + grub_errno = GRUB_ERR_NONE; + partnum = grub_strtoul (s, 0, 10) - 1; + if (grub_errno == GRUB_ERR_NONE) + { + if (sun_partition_map_iterate (disk, find_func)) + { + grub_free (p); + p = 0; + } + } + else + { + grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); + p = 0; + } + + return p; +} + +static char * +sun_partition_map_get_name (const grub_partition_t p) +{ + char *name; + + name = grub_malloc (13); + if (name) + grub_sprintf (name, "%d", p->index + 1); + + return name; +} + +/* Partition map type. */ +static struct grub_partition_map grub_sun_partition_map = + { + .name = "sun_partition_map", + .iterate = sun_partition_map_iterate, + .probe = sun_partition_map_probe, + .get_name = sun_partition_map_get_name + }; + +GRUB_MOD_INIT(sun_partition_map) +{ + grub_partition_map_register (&grub_sun_partition_map); +#ifndef GRUB_UTIL + my_mod = mod; +#endif +} + +GRUB_MOD_FINI(sun_partition_map) +{ + grub_partition_map_unregister (&grub_sun_partition_map); +} + diff --git a/stamp-h.in b/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/term/efi/console.c b/term/efi/console.c new file mode 100644 index 0000000..0bf2449 --- /dev/null +++ b/term/efi/console.c @@ -0,0 +1,378 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_uint8_t +grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW, + GRUB_EFI_BACKGROUND_BLACK); +static grub_uint8_t +grub_console_normal_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_LIGHTGRAY, + GRUB_EFI_BACKGROUND_BLACK); +static grub_uint8_t +grub_console_highlight_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_BLACK, + GRUB_EFI_BACKGROUND_LIGHTGRAY); + +static int read_key = -1; + +static grub_uint32_t +map_char (grub_uint32_t c) +{ + if (c > 0x7f) + { + /* Map some unicode characters to the EFI character. */ + switch (c) + { + case 0x2190: /* left arrow */ + c = 0x25c4; + break; + case 0x2191: /* up arrow */ + c = 0x25b2; + break; + case 0x2192: /* right arrow */ + c = 0x25ba; + break; + case 0x2193: /* down arrow */ + c = 0x25bc; + break; + case 0x2501: /* horizontal line */ + c = 0x2500; + break; + case 0x2503: /* vertical line */ + c = 0x2502; + break; + case 0x250F: /* upper-left corner */ + c = 0x250c; + break; + case 0x2513: /* upper-right corner */ + c = 0x2510; + break; + case 0x2517: /* lower-left corner */ + c = 0x2514; + break; + case 0x251B: /* lower-right corner */ + c = 0x2518; + break; + + default: + c = '?'; + break; + } + } + + return c; +} + +static void +grub_console_putchar (grub_uint32_t c) +{ + grub_efi_char16_t str[2]; + grub_efi_simple_text_output_interface_t *o; + + o = grub_efi_system_table->con_out; + + /* For now, do not try to use a surrogate pair. */ + if (c > 0xffff) + c = '?'; + + str[0] = (grub_efi_char16_t) map_char (c & 0xffff); + str[1] = 0; + + /* Should this test be cached? */ + if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS) + return; + + efi_call_2 (o->output_string, o, str); +} + +static grub_ssize_t +grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused))) +{ + /* For now, every printable character has the width 1. */ + return 1; +} + +static int +grub_console_checkkey (void) +{ + grub_efi_simple_input_interface_t *i; + grub_efi_input_key_t key; + grub_efi_status_t status; + + if (read_key >= 0) + return 1; + + i = grub_efi_system_table->con_in; + status = efi_call_2 (i->read_key_stroke, i, &key); +#if 0 + switch (status) + { + case GRUB_EFI_SUCCESS: + { + grub_uint16_t xy; + + xy = grub_getxy (); + grub_gotoxy (0, 0); + grub_printf ("scan_code=%x,unicode_char=%x ", + (unsigned) key.scan_code, + (unsigned) key.unicode_char); + grub_gotoxy (xy >> 8, xy & 0xff); + } + break; + + case GRUB_EFI_NOT_READY: + //grub_printf ("not ready "); + break; + + default: + //grub_printf ("device error "); + break; + } +#endif + + if (status == GRUB_EFI_SUCCESS) + { + switch (key.scan_code) + { + case 0x00: + read_key = key.unicode_char; + break; + case 0x01: + read_key = 16; + break; + case 0x02: + read_key = 14; + break; + case 0x03: + read_key = 6; + break; + case 0x04: + read_key = 2; + break; + case 0x05: + read_key = 1; + break; + case 0x06: + read_key = 5; + break; + case 0x07: + break; + case 0x08: + read_key = 4; + break; + case 0x09: + break; + case 0x0a: + break; + case 0x0b: + read_key = 24; + break; + case 0x0c: + read_key = 1; + break; + case 0x0d: + read_key = 5; + break; + case 0x17: + read_key = '\e'; + break; + default: + break; + } + } + + return read_key; +} + +static int +grub_console_getkey (void) +{ + grub_efi_simple_input_interface_t *i; + grub_efi_boot_services_t *b; + grub_efi_uintn_t index; + grub_efi_status_t status; + int key; + + if (read_key >= 0) + { + key = read_key; + read_key = -1; + return key; + } + + i = grub_efi_system_table->con_in; + b = grub_efi_system_table->boot_services; + + do + { + status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index); + if (status != GRUB_EFI_SUCCESS) + return -1; + + grub_console_checkkey (); + } + while (read_key < 0); + + key = read_key; + read_key = -1; + return key; +} + +static grub_uint16_t +grub_console_getwh (void) +{ + grub_efi_simple_text_output_interface_t *o; + grub_efi_uintn_t columns, rows; + + o = grub_efi_system_table->con_out; + if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS) + { + /* Why does this fail? */ + columns = 80; + rows = 25; + } + + return ((columns << 8) | rows); +} + +static grub_uint16_t +grub_console_getxy (void) +{ + grub_efi_simple_text_output_interface_t *o; + + o = grub_efi_system_table->con_out; + return ((o->mode->cursor_column << 8) | o->mode->cursor_row); +} + +static void +grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + grub_efi_simple_text_output_interface_t *o; + + o = grub_efi_system_table->con_out; + efi_call_3 (o->set_cursor_position, o, x, y); +} + +static void +grub_console_cls (void) +{ + grub_efi_simple_text_output_interface_t *o; + grub_efi_int32_t orig_attr; + + o = grub_efi_system_table->con_out; + orig_attr = o->mode->attribute; + efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK); + efi_call_1 (o->clear_screen, o); + efi_call_2 (o->set_attributes, o, orig_attr); +} + +static void +grub_console_setcolorstate (grub_term_color_state state) +{ + grub_efi_simple_text_output_interface_t *o; + + o = grub_efi_system_table->con_out; + + switch (state) { + case GRUB_TERM_COLOR_STANDARD: + efi_call_2 (o->set_attributes, o, grub_console_standard_color); + break; + case GRUB_TERM_COLOR_NORMAL: + efi_call_2 (o->set_attributes, o, grub_console_normal_color); + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + efi_call_2 (o->set_attributes, o, grub_console_highlight_color); + break; + default: + break; + } +} + +static void +grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +{ + grub_console_normal_color = normal_color; + grub_console_highlight_color = highlight_color; +} + +static void +grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +{ + *normal_color = grub_console_normal_color; + *highlight_color = grub_console_highlight_color; +} + +static void +grub_console_setcursor (int on) +{ + grub_efi_simple_text_output_interface_t *o; + + o = grub_efi_system_table->con_out; + efi_call_2 (o->enable_cursor, o, on); +} + +static struct grub_term_input grub_console_term_input = + { + .name = "console", + .checkkey = grub_console_checkkey, + .getkey = grub_console_getkey, + }; + +static struct grub_term_output grub_console_term_output = + { + .name = "console", + .putchar = grub_console_putchar, + .getcharwidth = grub_console_getcharwidth, + .getwh = grub_console_getwh, + .getxy = grub_console_getxy, + .gotoxy = grub_console_gotoxy, + .cls = grub_console_cls, + .setcolorstate = grub_console_setcolorstate, + .setcolor = grub_console_setcolor, + .getcolor = grub_console_getcolor, + .setcursor = grub_console_setcursor, + .flags = 0, + }; + +void +grub_console_init (void) +{ + /* FIXME: it is necessary to consider the case where no console control + is present but the default is already in text mode. */ + if (! grub_efi_set_text_mode (1)) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode"); + return; + } + + grub_term_register_input (&grub_console_term_input); + grub_term_register_output (&grub_console_term_output); +} + +void +grub_console_fini (void) +{ + grub_term_unregister_input (&grub_console_term_input); + grub_term_unregister_output (&grub_console_term_output); +} diff --git a/term/gfxterm.c b/term/gfxterm.c new file mode 100644 index 0000000..abb1b9e --- /dev/null +++ b/term/gfxterm.c @@ -0,0 +1,1181 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_VIDEO_WIDTH 640 +#define DEFAULT_VIDEO_HEIGHT 480 +#define DEFAULT_VIDEO_FLAGS 0 + +#define DEFAULT_BORDER_WIDTH 10 + +#define DEFAULT_STANDARD_COLOR 0x07 +#define DEFAULT_NORMAL_COLOR 0x07 +#define DEFAULT_HIGHLIGHT_COLOR 0x70 + +struct grub_dirty_region +{ + int top_left_x; + int top_left_y; + int bottom_right_x; + int bottom_right_y; +}; + +struct grub_colored_char +{ + /* An Unicode codepoint. */ + grub_uint32_t code; + + /* Color values. */ + grub_video_color_t fg_color; + grub_video_color_t bg_color; + + /* The width of this character minus one. */ + unsigned char width; + + /* The column index of this character. */ + unsigned char index; +}; + +struct grub_virtual_screen +{ + /* Dimensions of the virtual screen in pixels. */ + unsigned int width; + unsigned int height; + + /* Offset in the display in pixels. */ + unsigned int offset_x; + unsigned int offset_y; + + /* TTY Character sizes in pixes. */ + unsigned int normal_char_width; + unsigned int normal_char_height; + + /* Virtual screen TTY size in characters. */ + unsigned int columns; + unsigned int rows; + + /* Current cursor location in characters. */ + unsigned int cursor_x; + unsigned int cursor_y; + + /* Current cursor state. */ + int cursor_state; + + /* Font settings. */ + grub_font_t font; + + /* Terminal color settings. */ + grub_uint8_t standard_color_setting; + grub_uint8_t normal_color_setting; + grub_uint8_t highlight_color_setting; + grub_uint8_t term_color; + + /* Color settings. */ + grub_video_color_t fg_color; + grub_video_color_t bg_color; + + /* Text buffer for virtual screen. Contains (columns * rows) number + of entries. */ + struct grub_colored_char *text_buffer; +}; + +static struct grub_virtual_screen virtual_screen; + +static grub_dl_t my_mod; +static struct grub_video_mode_info mode_info; + +static struct grub_video_render_target *text_layer; + +static unsigned int bitmap_width; +static unsigned int bitmap_height; +static struct grub_video_bitmap *bitmap; + +static struct grub_dirty_region dirty_region; + +static void dirty_region_reset (void); + +static int dirty_region_is_empty (void); + +static void dirty_region_add (int x, int y, + unsigned int width, unsigned int height); + +static unsigned int calculate_normal_character_width (grub_font_t font); + +static unsigned char calculate_character_width (struct grub_font_glyph *glyph); + +static void +set_term_color (grub_uint8_t term_color) +{ + struct grub_video_render_target *old_target; + + /* Save previous target and switch to text layer. */ + grub_video_get_active_render_target (&old_target); + grub_video_set_active_render_target (text_layer); + + /* Map terminal color to text layer compatible video colors. */ + virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f); + + /* Special case: use black as transparent color. */ + if (((term_color >> 4) & 0x0f) == 0) + { + virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0); + } + else + { + virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f); + } + + /* Restore previous target. */ + grub_video_set_active_render_target (old_target); +} + +static void +grub_virtual_screen_free (void) +{ + /* If virtual screen has been allocated, free it. */ + if (virtual_screen.text_buffer != 0) + grub_free (virtual_screen.text_buffer); + + /* Reset virtual screen data. */ + grub_memset (&virtual_screen, 0, sizeof (virtual_screen)); + + /* Free render targets. */ + grub_video_delete_render_target (text_layer); + text_layer = 0; +} + +static grub_err_t +grub_virtual_screen_setup (unsigned int x, unsigned int y, + unsigned int width, unsigned int height, + const char *font_name) +{ + /* Free old virtual screen. */ + grub_virtual_screen_free (); + + /* Initialize with default data. */ + virtual_screen.font = grub_font_get (font_name); + if (!virtual_screen.font) + return grub_error (GRUB_ERR_BAD_FONT, + "No font loaded."); + virtual_screen.width = width; + virtual_screen.height = height; + virtual_screen.offset_x = x; + virtual_screen.offset_y = y; + virtual_screen.normal_char_width = + calculate_normal_character_width (virtual_screen.font); + virtual_screen.normal_char_height = + grub_font_get_max_char_height (virtual_screen.font); + virtual_screen.cursor_x = 0; + virtual_screen.cursor_y = 0; + virtual_screen.cursor_state = 1; + + /* Calculate size of text buffer. */ + virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width; + virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height; + + /* Allocate memory for text buffer. */ + virtual_screen.text_buffer = + (struct grub_colored_char *) grub_malloc (virtual_screen.columns + * virtual_screen.rows + * sizeof (*virtual_screen.text_buffer)); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Create new render target for text layer. */ + grub_video_create_render_target (&text_layer, + virtual_screen.width, + virtual_screen.height, + GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* As we want to have colors compatible with rendering target, + we can only have those after mode is initialized. */ + grub_video_set_active_render_target (text_layer); + + virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR; + virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR; + virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR; + + virtual_screen.term_color = virtual_screen.normal_color_setting; + + set_term_color (virtual_screen.term_color); + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + return grub_errno; +} + +static grub_err_t +grub_gfxterm_init (void) +{ + char *font_name; + char *modevar; + int width = DEFAULT_VIDEO_WIDTH; + int height = DEFAULT_VIDEO_HEIGHT; + int depth = -1; + int flags = DEFAULT_VIDEO_FLAGS; + grub_video_color_t color; + + /* Select the font to use. */ + font_name = grub_env_get ("gfxterm_font"); + if (! font_name) + font_name = ""; /* Allow fallback to any font. */ + + /* Parse gfxmode environment variable if set. */ + modevar = grub_env_get ("gfxmode"); + if (modevar) + { + char *tmp; + char *next_mode; + char *current_mode; + char *param; + char *value; + int mode_found = 0; + + /* Take copy of env.var. as we don't want to modify that. */ + tmp = grub_strdup (modevar); + modevar = tmp; + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Initialize next mode. */ + next_mode = modevar; + + /* Loop until all modes has been tested out. */ + while (next_mode != NULL) + { + /* Use last next_mode as current mode. */ + tmp = next_mode; + + /* Reset video mode settings. */ + width = DEFAULT_VIDEO_WIDTH; + height = DEFAULT_VIDEO_HEIGHT; + depth = -1; + flags = DEFAULT_VIDEO_FLAGS; + + /* Save position of next mode and separate modes. */ + next_mode = grub_strchr(next_mode, ';'); + if (next_mode) + { + *next_mode = 0; + next_mode++; + } + + /* Skip whitespace. */ + while (grub_isspace (*tmp)) + tmp++; + + /* Initialize token holders. */ + current_mode = tmp; + param = tmp; + value = NULL; + + /* Parse x[x]*/ + + /* Find width value. */ + value = param; + param = grub_strchr(param, 'x'); + if (param == NULL) + { + grub_err_t rc; + + /* First setup error message. */ + rc = grub_error (GRUB_ERR_BAD_ARGUMENT, + "Invalid mode: %s\n", + current_mode); + + /* Free memory before returning. */ + grub_free (modevar); + + return rc; + } + + *param = 0; + param++; + + width = grub_strtoul (value, 0, 0); + if (grub_errno != GRUB_ERR_NONE) + { + grub_err_t rc; + + /* First setup error message. */ + rc = grub_error (GRUB_ERR_BAD_ARGUMENT, + "Invalid mode: %s\n", + current_mode); + + /* Free memory before returning. */ + grub_free (modevar); + + return rc; + } + + /* Find height value. */ + value = param; + param = grub_strchr(param, 'x'); + if (param == NULL) + { + height = grub_strtoul (value, 0, 0); + if (grub_errno != GRUB_ERR_NONE) + { + grub_err_t rc; + + /* First setup error message. */ + rc = grub_error (GRUB_ERR_BAD_ARGUMENT, + "Invalid mode: %s\n", + current_mode); + + /* Free memory before returning. */ + grub_free (modevar); + + return rc; + } + } + else + { + /* We have optional color depth value. */ + *param = 0; + param++; + + height = grub_strtoul (value, 0, 0); + if (grub_errno != GRUB_ERR_NONE) + { + grub_err_t rc; + + /* First setup error message. */ + rc = grub_error (GRUB_ERR_BAD_ARGUMENT, + "Invalid mode: %s\n", + current_mode); + + /* Free memory before returning. */ + grub_free (modevar); + + return rc; + } + + /* Convert color depth value. */ + value = param; + depth = grub_strtoul (value, 0, 0); + if (grub_errno != GRUB_ERR_NONE) + { + grub_err_t rc; + + /* First setup error message. */ + rc = grub_error (GRUB_ERR_BAD_ARGUMENT, + "Invalid mode: %s\n", + current_mode); + + /* Free memory before returning. */ + grub_free (modevar); + + return rc; + } + } + + /* Try out video mode. */ + + /* If we have 8 or less bits, then assume that it is indexed color mode. */ + if ((depth <= 8) && (depth != -1)) + flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + + /* We have more than 8 bits, then assume that it is RGB color mode. */ + if (depth > 8) + flags |= GRUB_VIDEO_MODE_TYPE_RGB; + + /* If user requested specific depth, forward that information to driver. */ + if (depth != -1) + flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) + & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK; + + /* Try to initialize requested mode. Ignore any errors. */ + grub_error_push (); + if (grub_video_setup (width, height, flags) != GRUB_ERR_NONE) + { + grub_error_pop (); + continue; + } + + /* Figure out what mode we ended up. */ + if (grub_video_get_info (&mode_info) != GRUB_ERR_NONE) + { + /* Couldn't get video mode info, restore old mode and continue to next one. */ + grub_error_pop (); + + grub_video_restore (); + continue; + } + + /* Restore state of error stack. */ + grub_error_pop (); + + /* Mode found! Exit loop. */ + mode_found = 1; + break; + } + + /* Free memory. */ + grub_free (modevar); + + if (!mode_found) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "No suitable mode found."); + } + else + { + /* No gfxmode variable set, use defaults. */ + + /* If we have 8 or less bits, then assume that it is indexed color mode. */ + if ((depth <= 8) && (depth != -1)) + flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + + /* We have more than 8 bits, then assume that it is RGB color mode. */ + if (depth > 8) + flags |= GRUB_VIDEO_MODE_TYPE_RGB; + + /* If user requested specific depth, forward that information to driver. */ + if (depth != -1) + flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) + & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK; + + /* Initialize user requested mode. */ + if (grub_video_setup (width, height, flags) != GRUB_ERR_NONE) + return grub_errno; + + /* Figure out what mode we ended up. */ + if (grub_video_get_info (&mode_info) != GRUB_ERR_NONE) + { + grub_video_restore (); + return grub_errno; + } + } + + /* Make sure screen is black. */ + color = grub_video_map_rgb (0, 0, 0); + grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + bitmap = 0; + + /* Leave borders for virtual screen. */ + width = mode_info.width - (2 * DEFAULT_BORDER_WIDTH); + height = mode_info.height - (2 * DEFAULT_BORDER_WIDTH); + + /* Create virtual screen. */ + if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH, DEFAULT_BORDER_WIDTH, + width, height, font_name) != GRUB_ERR_NONE) + { + grub_video_restore (); + return grub_errno; + } + + /* Mark whole screen as dirty. */ + dirty_region_reset (); + dirty_region_add (0, 0, mode_info.width, mode_info.height); + + return (grub_errno = GRUB_ERR_NONE); +} + +static grub_err_t +grub_gfxterm_fini (void) +{ + if (bitmap) + { + grub_video_bitmap_destroy (bitmap); + bitmap = 0; + } + + grub_virtual_screen_free (); + + grub_video_restore (); + + return GRUB_ERR_NONE; +} + +static void +redraw_screen_rect (unsigned int x, unsigned int y, + unsigned int width, unsigned int height) +{ + grub_video_color_t color; + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + + if (bitmap) + { + /* Render bitmap as background. */ + grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y, + x, y, + width, height); + + /* If bitmap is smaller than requested blit area, use background + color. */ + color = virtual_screen.bg_color; + + /* Fill right side of the bitmap if needed. */ + if ((x + width >= bitmap_width) && (y < bitmap_height)) + { + int w = (x + width) - bitmap_width; + int h = height; + unsigned int tx = x; + + if (y + height >= bitmap_height) + { + h = bitmap_height - y; + } + + if (bitmap_width > tx) + { + tx = bitmap_width; + } + + /* Render background layer. */ + grub_video_fill_rect (color, tx, y, w, h); + } + + /* Fill bottom side of the bitmap if needed. */ + if (y + height >= bitmap_height) + { + int h = (y + height) - bitmap_height; + unsigned int ty = y; + + if (bitmap_height > ty) + { + ty = bitmap_height; + } + + /* Render background layer. */ + grub_video_fill_rect (color, x, ty, width, h); + } + + /* Render text layer as blended. */ + grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, x, y, + x - virtual_screen.offset_x, + y - virtual_screen.offset_y, + width, height); + } + else + { + /* Render background layer. */ + color = virtual_screen.bg_color; + grub_video_fill_rect (color, x, y, width, height); + + /* Render text layer as replaced (to get texts background color). */ + grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_REPLACE, x, y, + x - virtual_screen.offset_x, + y - virtual_screen.offset_y, + width, height); + } +} + +static void +dirty_region_reset (void) +{ + dirty_region.top_left_x = -1; + dirty_region.top_left_y = -1; + dirty_region.bottom_right_x = -1; + dirty_region.bottom_right_y = -1; +} + +static int +dirty_region_is_empty (void) +{ + if ((dirty_region.top_left_x == -1) + || (dirty_region.top_left_y == -1) + || (dirty_region.bottom_right_x == -1) + || (dirty_region.bottom_right_y == -1)) + return 1; + return 0; +} + +static void +dirty_region_add (int x, int y, unsigned int width, unsigned int height) +{ + if ((width == 0) || (height == 0)) + return; + + if (dirty_region_is_empty ()) + { + dirty_region.top_left_x = x; + dirty_region.top_left_y = y; + dirty_region.bottom_right_x = x + width - 1; + dirty_region.bottom_right_y = y + height - 1; + } + else + { + if (x < dirty_region.top_left_x) + dirty_region.top_left_x = x; + if (y < dirty_region.top_left_y) + dirty_region.top_left_y = y; + if ((x + (int)width - 1) > dirty_region.bottom_right_x) + dirty_region.bottom_right_x = x + width - 1; + if ((y + (int)height - 1) > dirty_region.bottom_right_y) + dirty_region.bottom_right_y = y + height - 1; + } +} + +static void +dirty_region_add_virtualscreen (void) +{ + /* Mark virtual screen as dirty. */ + dirty_region_add (virtual_screen.offset_x, virtual_screen.offset_y, + virtual_screen.width, virtual_screen.height); +} + + +static void +dirty_region_redraw (void) +{ + int x; + int y; + int width; + int height; + + if (dirty_region_is_empty ()) + return; + + x = dirty_region.top_left_x; + y = dirty_region.top_left_y; + + width = dirty_region.bottom_right_x - x + 1; + height = dirty_region.bottom_right_y - y + 1; + + redraw_screen_rect (x, y, width, height); + + dirty_region_reset (); +} + +static void +write_char (void) +{ + struct grub_colored_char *p; + struct grub_font_glyph *glyph; + grub_video_color_t color; + grub_video_color_t bgcolor; + unsigned int x; + unsigned int y; + int ascent; + unsigned int height; + unsigned int width; + + /* Find out active character. */ + p = (virtual_screen.text_buffer + + virtual_screen.cursor_x + + (virtual_screen.cursor_y * virtual_screen.columns)); + + p -= p->index; + + /* Get glyph for character. */ + glyph = grub_font_get_glyph (virtual_screen.font, p->code); + ascent = grub_font_get_ascent (virtual_screen.font); + + width = virtual_screen.normal_char_width * calculate_character_width(glyph); + height = virtual_screen.normal_char_height; + + color = p->fg_color; + bgcolor = p->bg_color; + + x = virtual_screen.cursor_x * virtual_screen.normal_char_width; + y = virtual_screen.cursor_y * virtual_screen.normal_char_height; + + /* Render glyph to text layer. */ + grub_video_set_active_render_target (text_layer); + grub_video_fill_rect (bgcolor, x, y, width, height); + grub_font_draw_glyph (glyph, color, x, y + ascent); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + /* Mark character to be drawn. */ + dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, + width, height); +} + +static void +draw_cursor (int show) +{ + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + grub_video_color_t color; + + /* Determine cursor properties and position on text layer. */ + x = virtual_screen.cursor_x * virtual_screen.normal_char_width; + y = (virtual_screen.cursor_y * virtual_screen.normal_char_height + + grub_font_get_ascent (virtual_screen.font)); + width = virtual_screen.normal_char_width; + height = 2; + + if (show) + { + color = virtual_screen.fg_color; + } + else + { + color = virtual_screen.bg_color; + y = virtual_screen.cursor_y * virtual_screen.normal_char_height; + height = virtual_screen.normal_char_height; + } + + /* Render cursor to text layer. */ + grub_video_set_active_render_target (text_layer); + grub_video_fill_rect (color, x, y, width, height); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + /* Mark cursor to be redrawn. */ + dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, + width, height); +} + +static void +scroll_up (void) +{ + unsigned int i; + grub_video_color_t color; + + /* If we don't have background bitmap, remove cursor. */ + if (!bitmap) + { + /* Remove cursor. */ + draw_cursor (0); + + /* Redraw only changed regions. */ + dirty_region_redraw (); + } + + /* Scroll text buffer with one line to up. */ + grub_memmove (virtual_screen.text_buffer, + virtual_screen.text_buffer + virtual_screen.columns, + sizeof (*virtual_screen.text_buffer) + * virtual_screen.columns + * (virtual_screen.rows - 1)); + + /* Clear last line in text buffer. */ + for (i = virtual_screen.columns * (virtual_screen.rows - 1); + i < virtual_screen.columns * virtual_screen.rows; + i++) + { + virtual_screen.text_buffer[i].code = ' '; + virtual_screen.text_buffer[i].fg_color = virtual_screen.fg_color; + virtual_screen.text_buffer[i].bg_color = virtual_screen.bg_color; + virtual_screen.text_buffer[i].width = 0; + virtual_screen.text_buffer[i].index = 0; + } + + /* Scroll physical screen. */ + grub_video_set_active_render_target (text_layer); + color = virtual_screen.bg_color; + grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */ + if (bitmap) + { + /* Mark virtual screen to be redrawn. */ + dirty_region_add_virtualscreen (); + } + else + { + /* Clear new border area. */ + grub_video_fill_rect (color, + virtual_screen.offset_x, virtual_screen.offset_y, + virtual_screen.width, virtual_screen.normal_char_height); + + /* Scroll physical screen. */ + grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + + /* Draw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); + } +} + +static void +grub_gfxterm_putchar (grub_uint32_t c) +{ + if (c == '\a') + /* FIXME */ + return; + + if (c == '\b' || c == '\n' || c == '\r') + { + /* Erase current cursor, if any. */ + if (virtual_screen.cursor_state) + draw_cursor (0); + + switch (c) + { + case '\b': + if (virtual_screen.cursor_x > 0) + virtual_screen.cursor_x--; + break; + + case '\n': + if (virtual_screen.cursor_y >= virtual_screen.rows - 1) + scroll_up (); + else + virtual_screen.cursor_y++; + break; + + case '\r': + virtual_screen.cursor_x = 0; + break; + } + + /* Redraw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); + } + else + { + struct grub_font_glyph *glyph; + struct grub_colored_char *p; + unsigned char char_width; + + /* Erase current cursor, if any. */ + if (virtual_screen.cursor_state) + draw_cursor (0); + + /* Get properties of the character. */ + glyph = grub_font_get_glyph (virtual_screen.font, c); + + /* Calculate actual character width for glyph. This is number of + times of normal_font_width. */ + char_width = calculate_character_width(glyph); + + /* If we are about to exceed line length, wrap to next line. */ + if (virtual_screen.cursor_x + char_width > virtual_screen.columns) + grub_putchar ('\n'); + + /* Find position on virtual screen, and fill information. */ + p = (virtual_screen.text_buffer + + virtual_screen.cursor_x + + virtual_screen.cursor_y * virtual_screen.columns); + p->code = c; + p->fg_color = virtual_screen.fg_color; + p->bg_color = virtual_screen.bg_color; + p->width = char_width - 1; + p->index = 0; + + /* If we have large glyph, add fixup info. */ + if (char_width > 1) + { + unsigned i; + + for (i = 1; i < char_width; i++) + { + p[i].code = ' '; + p[i].width = char_width - 1; + p[i].index = i; + } + } + + /* Draw glyph. */ + write_char (); + + /* Make sure we scroll screen when needed and wrap line correctly. */ + virtual_screen.cursor_x += char_width; + if (virtual_screen.cursor_x >= virtual_screen.columns) + { + virtual_screen.cursor_x = 0; + + if (virtual_screen.cursor_y >= virtual_screen.rows - 1) + scroll_up (); + else + virtual_screen.cursor_y++; + } + + /* Draw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); + } +} + +/* Use ASCII characters to determine normal character width. */ +static unsigned int +calculate_normal_character_width (grub_font_t font) +{ + struct grub_font_glyph *glyph; + unsigned int width = 0; + unsigned int i; + + /* Get properties of every printable ASCII character. */ + for (i = 32; i < 127; i++) + { + glyph = grub_font_get_glyph (font, i); + + /* Skip unknown characters. Should never happen on normal conditions. */ + if (! glyph) + continue; + + if (glyph->device_width > width) + width = glyph->device_width; + } + + return width; +} + +static unsigned char +calculate_character_width (struct grub_font_glyph *glyph) +{ + if (! glyph || glyph->device_width == 0) + return 1; + + return (glyph->device_width + + (virtual_screen.normal_char_width - 1)) + / virtual_screen.normal_char_width; +} + +static grub_ssize_t +grub_gfxterm_getcharwidth (grub_uint32_t c) +{ + struct grub_font_glyph *glyph; + unsigned char char_width; + + /* Get properties of the character. */ + glyph = grub_font_get_glyph (virtual_screen.font, c); + + /* Calculate actual character width for glyph. */ + char_width = calculate_character_width (glyph); + + return char_width; +} + +static grub_uint16_t +grub_virtual_screen_getwh (void) +{ + return (virtual_screen.columns << 8) | virtual_screen.rows; +} + +static grub_uint16_t +grub_virtual_screen_getxy (void) +{ + return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y); +} + +static void +grub_gfxterm_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + if (x >= virtual_screen.columns) + x = virtual_screen.columns - 1; + + if (y >= virtual_screen.rows) + y = virtual_screen.rows - 1; + + /* Erase current cursor, if any. */ + if (virtual_screen.cursor_state) + draw_cursor (0); + + virtual_screen.cursor_x = x; + virtual_screen.cursor_y = y; + + /* Draw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); +} + +static void +grub_virtual_screen_cls (void) +{ + grub_uint32_t i; + + for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) + { + virtual_screen.text_buffer[i].code = ' '; + virtual_screen.text_buffer[i].fg_color = virtual_screen.fg_color; + virtual_screen.text_buffer[i].bg_color = virtual_screen.bg_color; + virtual_screen.text_buffer[i].width = 0; + virtual_screen.text_buffer[i].index = 0; + } + + virtual_screen.cursor_x = virtual_screen.cursor_y = 0; +} + +static void +grub_gfxterm_cls (void) +{ + grub_video_color_t color; + + /* Clear virtual screen. */ + grub_virtual_screen_cls (); + + /* Clear text layer. */ + grub_video_set_active_render_target (text_layer); + color = virtual_screen.bg_color; + grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + /* Mark virtual screen to be redrawn. */ + dirty_region_add_virtualscreen (); +} + +static void +grub_virtual_screen_setcolorstate (grub_term_color_state state) +{ + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + virtual_screen.term_color = virtual_screen.standard_color_setting; + break; + + case GRUB_TERM_COLOR_NORMAL: + virtual_screen.term_color = virtual_screen.normal_color_setting; + break; + + case GRUB_TERM_COLOR_HIGHLIGHT: + virtual_screen.term_color = virtual_screen.highlight_color_setting; + break; + + default: + break; + } + + /* Change color to virtual terminal. */ + set_term_color (virtual_screen.term_color); +} + +static void +grub_virtual_screen_setcolor (grub_uint8_t normal_color, + grub_uint8_t highlight_color) +{ + virtual_screen.normal_color_setting = normal_color; + virtual_screen.highlight_color_setting = highlight_color; +} + +static void +grub_virtual_screen_getcolor (grub_uint8_t *normal_color, + grub_uint8_t *highlight_color) +{ + *normal_color = virtual_screen.normal_color_setting; + *highlight_color = virtual_screen.highlight_color_setting; +} + +static void +grub_gfxterm_setcursor (int on) +{ + if (virtual_screen.cursor_state != on) + { + if (virtual_screen.cursor_state) + draw_cursor (0); + else + draw_cursor (1); + + virtual_screen.cursor_state = on; + } +} + +static void +grub_gfxterm_refresh (void) +{ + /* Redraw only changed regions. */ + dirty_region_redraw (); +} + +static grub_err_t +grub_gfxterm_background_image_cmd (struct grub_arg_list *state __attribute__ ((unused)), + int argc, + char **args) +{ + /* Check that we have video adapter active. */ + if (grub_video_get_info(NULL) != GRUB_ERR_NONE) + return grub_errno; + + /* Destroy existing background bitmap if loaded. */ + if (bitmap) + { + grub_video_bitmap_destroy (bitmap); + bitmap = 0; + + /* Mark whole screen as dirty. */ + dirty_region_reset (); + dirty_region_add (0, 0, mode_info.width, mode_info.height); + } + + /* If filename was provided, try to load that. */ + if (argc >= 1) + { + /* Try to load new one. */ + grub_video_bitmap_load (&bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* If bitmap was loaded correctly, display it. */ + if (bitmap) + { + /* Determine bitmap dimensions. */ + bitmap_width = grub_video_bitmap_get_width (bitmap); + bitmap_height = grub_video_bitmap_get_width (bitmap); + + /* Mark whole screen as dirty. */ + dirty_region_reset (); + dirty_region_add (0, 0, mode_info.width, mode_info.height); + } + } + + /* All was ok. */ + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + +static struct grub_term_output grub_video_term = + { + .name = "gfxterm", + .init = grub_gfxterm_init, + .fini = grub_gfxterm_fini, + .putchar = grub_gfxterm_putchar, + .getcharwidth = grub_gfxterm_getcharwidth, + .getwh = grub_virtual_screen_getwh, + .getxy = grub_virtual_screen_getxy, + .gotoxy = grub_gfxterm_gotoxy, + .cls = grub_gfxterm_cls, + .setcolorstate = grub_virtual_screen_setcolorstate, + .setcolor = grub_virtual_screen_setcolor, + .getcolor = grub_virtual_screen_getcolor, + .setcursor = grub_gfxterm_setcursor, + .refresh = grub_gfxterm_refresh, + .flags = 0, + .next = 0 + }; + +GRUB_MOD_INIT(term_gfxterm) +{ + my_mod = mod; + grub_term_register_output (&grub_video_term); + + grub_register_command ("background_image", + grub_gfxterm_background_image_cmd, + GRUB_COMMAND_FLAG_BOTH, + "background_image", + "Load background image for active terminal", + 0); +} + +GRUB_MOD_FINI(term_gfxterm) +{ + grub_unregister_command ("bgimage"); + grub_term_unregister_output (&grub_video_term); +} diff --git a/term/i386/pc/at_keyboard.c b/term/i386/pc/at_keyboard.c new file mode 100644 index 0000000..ff5246d --- /dev/null +++ b/term/i386/pc/at_keyboard.c @@ -0,0 +1,235 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static short at_keyboard_status = 0; + +#define KEYBOARD_STATUS_SHIFT_L (1 << 0) +#define KEYBOARD_STATUS_SHIFT_R (1 << 1) +#define KEYBOARD_STATUS_ALT_L (1 << 2) +#define KEYBOARD_STATUS_ALT_R (1 << 3) +#define KEYBOARD_STATUS_CTRL_L (1 << 4) +#define KEYBOARD_STATUS_CTRL_R (1 << 5) +#define KEYBOARD_STATUS_CAPS_LOCK (1 << 6) + +static char keyboard_map[128] = +{ + '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\n', '\0', 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', '\0', '*', + '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME, + GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END, + GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, + OLPC_RIGHT +}; + +static char keyboard_map_shift[128] = +{ + '\0', '\0', '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', '\0', '\0', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?' +}; + +static grub_uint8_t grub_keyboard_controller_orig; + +static void +grub_keyboard_controller_write (grub_uint8_t c) +{ + while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); + grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS); + grub_outb (c, KEYBOARD_REG_DATA); +} + +static grub_uint8_t +grub_keyboard_controller_read (void) +{ + while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); + grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS); + return grub_inb (KEYBOARD_REG_DATA); +} + +/* FIXME: This should become an interrupt service routine. For now + it's just used to catch events from control keys. */ +static void +grub_keyboard_isr (char key) +{ + char is_make = KEYBOARD_ISMAKE (key); + key = KEYBOARD_SCANCODE (key); + if (is_make) + switch (key) + { + case SHIFT_L: + at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L; + break; + case SHIFT_R: + at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R; + break; + case CTRL: + at_keyboard_status |= KEYBOARD_STATUS_CTRL_L; + break; + case ALT: + at_keyboard_status |= KEYBOARD_STATUS_ALT_L; + break; + default: + /* Skip grub_dprintf. */ + return; + } + else + switch (key) + { + case SHIFT_L: + at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L; + break; + case SHIFT_R: + at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R; + break; + case CTRL: + at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L; + break; + case ALT: + at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L; + break; + default: + /* Skip grub_dprintf. */ + return; + } +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "Control key 0x%0x was %s\n", key, is_make ? "pressed" : "unpressed"); +#endif +} + +/* If there is a raw key pending, return it; otherwise return -1. */ +static int +grub_keyboard_getkey (void) +{ + grub_uint8_t key; + if (KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + return -1; + key = grub_inb (KEYBOARD_REG_DATA); + /* FIXME */ grub_keyboard_isr (key); + if (! KEYBOARD_ISMAKE (key)) + return -1; + return (KEYBOARD_SCANCODE (key)); +} + +/* If there is a character pending, return it; otherwise return -1. */ +static int +grub_at_keyboard_checkkey (void) +{ + int code, key; + code = grub_keyboard_getkey (); + if (code == -1) + return -1; +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "Detected key 0x%x\n", key); +#endif + switch (code) + { + case CAPS_LOCK: + at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK; + /* Caps lock sends scan code twice. Get the second one and discard it. */ + while (grub_keyboard_getkey () == -1); +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)); +#endif + key = -1; + break; + default: + if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) + key = keyboard_map[code] - 'a' + 1; + else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R)) + && keyboard_map_shift[code]) + key = keyboard_map_shift[code]; + else + key = keyboard_map[code]; + + if (key == 0) + grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); + + if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK) + { + if ((key >= 'a') && (key <= 'z')) + key += 'A' - 'a'; + else if ((key >= 'A') && (key <= 'Z')) + key += 'a' - 'A'; + } + } + return (int) key; +} + +static int +grub_at_keyboard_getkey (void) +{ + int key; + do + { + key = grub_at_keyboard_checkkey (); + } while (key == -1); + return key; +} + +static grub_err_t +grub_keyboard_controller_init (void) +{ + grub_keyboard_controller_orig = grub_keyboard_controller_read (); + grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_keyboard_controller_fini (void) +{ + grub_keyboard_controller_write (grub_keyboard_controller_orig); + return GRUB_ERR_NONE; +} + +static struct grub_term_input grub_at_keyboard_term = + { + .name = "at_keyboard", + .init = grub_keyboard_controller_init, + .fini = grub_keyboard_controller_fini, + .checkkey = grub_at_keyboard_checkkey, + .getkey = grub_at_keyboard_getkey, + }; + +GRUB_MOD_INIT(at_keyboard) +{ + grub_term_register_input (&grub_at_keyboard_term); +} + +GRUB_MOD_FINI(at_keyboard) +{ + grub_term_unregister_input (&grub_at_keyboard_term); +} diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c new file mode 100644 index 0000000..6c6be46 --- /dev/null +++ b/term/i386/pc/console.c @@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static struct grub_term_input grub_console_term_input = + { + .name = "console", + .checkkey = grub_console_checkkey, + .getkey = grub_console_getkey, + }; + +static struct grub_term_output grub_console_term_output = + { + .name = "console", + .putchar = grub_console_putchar, + .getcharwidth = grub_console_getcharwidth, + .getwh = grub_console_getwh, + .getxy = grub_console_getxy, + .gotoxy = grub_console_gotoxy, + .cls = grub_console_cls, + .setcolorstate = grub_console_setcolorstate, + .setcolor = grub_console_setcolor, + .getcolor = grub_console_getcolor, + .setcursor = grub_console_setcursor, + .flags = 0, + }; + +void +grub_console_init (void) +{ + grub_term_register_output (&grub_console_term_output); + grub_term_register_input (&grub_console_term_input); +} + +void +grub_console_fini (void) +{ + /* This is to make sure the console is restored to text mode before + we boot. */ + grub_term_set_current_output (&grub_console_term_output); + + grub_term_unregister_input (&grub_console_term_input); + grub_term_unregister_output (&grub_console_term_output); +} diff --git a/term/i386/pc/serial.c b/term/i386/pc/serial.c new file mode 100644 index 0000000..03a46ba --- /dev/null +++ b/term/i386/pc/serial.c @@ -0,0 +1,627 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEXT_WIDTH 80 +#define TEXT_HEIGHT 25 + +static unsigned int xpos, ypos; +static unsigned int keep_track = 1; +static unsigned int registered = 0; + +/* An input buffer. */ +static char input_buf[8]; +static unsigned int npending = 0; + +/* Argument options. */ +static const struct grub_arg_option options[] = +{ + {"unit", 'u', 0, "Set the serial unit", 0, ARG_TYPE_INT}, + {"port", 'p', 0, "Set the serial port address", 0, ARG_TYPE_STRING}, + {"speed", 's', 0, "Set the serial port speed", 0, ARG_TYPE_INT}, + {"word", 'w', 0, "Set the serial port word length", 0, ARG_TYPE_INT}, + {"parity", 'r', 0, "Set the serial port parity", 0, ARG_TYPE_STRING}, + {"stop", 't', 0, "Set the serial port stop bits", 0, ARG_TYPE_INT}, + {0, 0, 0, 0, 0, 0} +}; + +/* Serial port settings. */ +struct serial_port +{ + unsigned short port; + unsigned short divisor; + unsigned short word_len; + unsigned int parity; + unsigned short stop_bits; +}; + +/* Serial port settings. */ +static struct serial_port serial_settings; + +#ifdef GRUB_MACHINE_PCBIOS +/* The BIOS data area. */ +static const unsigned short *serial_hw_io_addr = (const unsigned short *) 0x0400; +#define GRUB_SERIAL_PORT_NUM 4 +#else +static const unsigned short serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; +#define GRUB_SERIAL_PORT_NUM (sizeof(serial_hw_io_addr)/sizeof(serial_hw_io_addr[0])) +#endif + +/* Return the port number for the UNITth serial device. */ +static inline unsigned short +serial_hw_get_port (const unsigned int unit) +{ + if (unit < GRUB_SERIAL_PORT_NUM) + return serial_hw_io_addr[unit]; + else + return 0; +} + +/* Fetch a key. */ +static int +serial_hw_fetch (void) +{ + if (grub_inb (serial_settings.port + UART_LSR) & UART_DATA_READY) + return grub_inb (serial_settings.port + UART_RX); + + return -1; +} + +/* Put a character. */ +static void +serial_hw_put (const int c) +{ + unsigned int timeout = 100000; + + /* Wait until the transmitter holding register is empty. */ + while ((grub_inb (serial_settings.port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0) + { + if (--timeout == 0) + /* There is something wrong. But what can I do? */ + return; + } + + grub_outb (c, serial_settings.port + UART_TX); +} + +static void +serial_translate_key_sequence (void) +{ + static struct + { + char key; + char ascii; + } + three_code_table[] = + { + {'A', 16}, + {'B', 14}, + {'C', 6}, + {'D', 2}, + {'F', 5}, + {'H', 1}, + {'4', 4} + }; + + static struct + { + short key; + char ascii; + } + four_code_table[] = + { + {('1' | ('~' << 8)), 1}, + {('3' | ('~' << 8)), 4}, + {('5' | ('~' << 8)), 7}, + {('6' | ('~' << 8)), 3} + }; + + /* The buffer must start with "ESC [". */ + if (*((unsigned short *) input_buf) != ('\e' | ('[' << 8))) + return; + + if (npending >= 3) + { + unsigned int i; + + for (i = 0; + i < sizeof (three_code_table) / sizeof (three_code_table[0]); + i++) + if (three_code_table[i].key == input_buf[2]) + { + input_buf[0] = three_code_table[i].ascii; + npending -= 2; + grub_memmove (input_buf + 1, input_buf + 3, npending - 1); + return; + } + } + + if (npending >= 4) + { + unsigned int i; + short key = *((short *) (input_buf + 2)); + + for (i = 0; + i < sizeof (four_code_table) / sizeof (four_code_table[0]); + i++) + if (four_code_table[i].key == key) + { + input_buf[0] = four_code_table[i].ascii; + npending -= 3; + grub_memmove (input_buf + 1, input_buf + 4, npending - 1); + return; + } + } +} + +static int +fill_input_buf (const int nowait) +{ + int i; + + for (i = 0; i < 10000 && npending < sizeof (input_buf); i++) + { + int c; + + c = serial_hw_fetch (); + if (c >= 0) + { + input_buf[npending++] = c; + + /* Reset the counter to zero, to wait for the same interval. */ + i = 0; + } + + if (nowait) + break; + } + + /* Translate some key sequences. */ + serial_translate_key_sequence (); + + return npending; +} + +/* Convert speed to divisor. */ +static unsigned short +serial_get_divisor (unsigned int speed) +{ + unsigned int i; + + /* The structure for speed vs. divisor. */ + struct divisor + { + unsigned int speed; + unsigned short div; + }; + + /* The table which lists common configurations. */ + /* 1843200 / (speed * 16) */ + static struct divisor divisor_tab[] = + { + { 2400, 0x0030 }, + { 4800, 0x0018 }, + { 9600, 0x000C }, + { 19200, 0x0006 }, + { 38400, 0x0003 }, + { 57600, 0x0002 }, + { 115200, 0x0001 } + }; + + /* Set the baud rate. */ + for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++) + if (divisor_tab[i].speed == speed) + return divisor_tab[i].div; + return 0; +} + +/* The serial version of checkkey. */ +static int +grub_serial_checkkey (void) +{ + if (fill_input_buf (1)) + return input_buf[0]; + else + return -1; +} + +/* The serial version of getkey. */ +static int +grub_serial_getkey (void) +{ + int c; + + while (! fill_input_buf (0)) + ; + + c = input_buf[0]; + grub_memmove (input_buf, input_buf + 1, --npending); + + return c; +} + +/* Initialize a serial device. PORT is the port number for a serial device. + SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600, + 19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used + for the device. Likewise, PARITY is the type of the parity and + STOP_BIT_LEN is the length of the stop bit. The possible values for + WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as + macros. */ +static grub_err_t +serial_hw_init (void) +{ + unsigned char status = 0; + + /* Turn off the interrupt. */ + grub_outb (0, serial_settings.port + UART_IER); + + /* Set DLAB. */ + grub_outb (UART_DLAB, serial_settings.port + UART_LCR); + + /* Set the baud rate. */ + grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL); + grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH); + + /* Set the line status. */ + status |= (serial_settings.parity + | serial_settings.word_len + | serial_settings.stop_bits); + grub_outb (status, serial_settings.port + UART_LCR); + + /* Enable the FIFO. */ + grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR); + + /* Turn on DTR, RTS, and OUT2. */ + grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR); + + /* Drain the input buffer. */ + while (grub_serial_checkkey () != -1) + (void) grub_serial_getkey (); + + /* FIXME: should check if the serial terminal was found. */ + + return GRUB_ERR_NONE; +} + +/* The serial version of putchar. */ +static void +grub_serial_putchar (grub_uint32_t c) +{ + /* Keep track of the cursor. */ + if (keep_track) + { + /* The serial terminal does not have VGA fonts. */ + if (c > 0x7F) + { + /* Better than nothing. */ + switch (c) + { + case GRUB_TERM_DISP_LEFT: + c = '<'; + break; + + case GRUB_TERM_DISP_UP: + c = '^'; + break; + + case GRUB_TERM_DISP_RIGHT: + c = '>'; + break; + + case GRUB_TERM_DISP_DOWN: + c = 'v'; + break; + + case GRUB_TERM_DISP_HLINE: + c = '-'; + break; + + case GRUB_TERM_DISP_VLINE: + c = '|'; + break; + + case GRUB_TERM_DISP_UL: + case GRUB_TERM_DISP_UR: + case GRUB_TERM_DISP_LL: + case GRUB_TERM_DISP_LR: + c = '+'; + break; + + default: + c = '?'; + break; + } + } + + switch (c) + { + case '\a': + break; + + case '\b': + case 127: + if (xpos > 0) + xpos--; + break; + + case '\n': + if (ypos < TEXT_HEIGHT) + ypos++; + break; + + case '\r': + xpos = 0; + break; + + default: + if (xpos >= TEXT_WIDTH) + { + grub_putchar ('\r'); + grub_putchar ('\n'); + } + xpos++; + break; + } + } + + serial_hw_put (c); +} + +static grub_ssize_t +grub_serial_getcharwidth (grub_uint32_t c __attribute__ ((unused))) +{ + return 1; +} + +static grub_uint16_t +grub_serial_getwh (void) +{ + return (TEXT_WIDTH << 8) | TEXT_HEIGHT; +} + +static grub_uint16_t +grub_serial_getxy (void) +{ + return ((xpos << 8) | ypos); +} + +static void +grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + if (x > TEXT_WIDTH || y > TEXT_HEIGHT) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", x, y); + } + else + { + keep_track = 0; + grub_terminfo_gotoxy (x, y); + keep_track = 1; + + xpos = x; + ypos = y; + } +} + +static void +grub_serial_cls (void) +{ + keep_track = 0; + grub_terminfo_cls (); + keep_track = 1; + + xpos = ypos = 0; +} + +static void +grub_serial_setcolorstate (const grub_term_color_state state) +{ + keep_track = 0; + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + grub_terminfo_reverse_video_off (); + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + grub_terminfo_reverse_video_on (); + break; + default: + break; + } + keep_track = 1; +} + +static void +grub_serial_setcursor (const int on) +{ + if (on) + grub_terminfo_cursor_on (); + else + grub_terminfo_cursor_off (); +} + +static struct grub_term_input grub_serial_term_input = +{ + .name = "serial", + .checkkey = grub_serial_checkkey, + .getkey = grub_serial_getkey, +}; + +static struct grub_term_output grub_serial_term_output = +{ + .name = "serial", + .putchar = grub_serial_putchar, + .getcharwidth = grub_serial_getcharwidth, + .getwh = grub_serial_getwh, + .getxy = grub_serial_getxy, + .gotoxy = grub_serial_gotoxy, + .cls = grub_serial_cls, + .setcolorstate = grub_serial_setcolorstate, + .setcursor = grub_serial_setcursor, + .flags = 0, +}; + + + +static grub_err_t +grub_cmd_serial (struct grub_arg_list *state, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct serial_port backup_settings = serial_settings; + grub_err_t hwiniterr; + + if (state[0].set) + { + unsigned int unit; + + unit = grub_strtoul (state[0].arg, 0, 0); + serial_settings.port = serial_hw_get_port (unit); + if (!serial_settings.port) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number."); + } + + if (state[1].set) + serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0); + + if (state[2].set) + { + unsigned long speed; + + speed = grub_strtoul (state[2].arg, 0, 0); + serial_settings.divisor = serial_get_divisor ((unsigned int) speed); + if (serial_settings.divisor == 0) + { + serial_settings = backup_settings; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed"); + } + } + + if (state[3].set) + { + if (! grub_strcmp (state[3].arg, "5")) + serial_settings.word_len = UART_5BITS_WORD; + else if (! grub_strcmp (state[3].arg, "6")) + serial_settings.word_len = UART_6BITS_WORD; + else if (! grub_strcmp (state[3].arg, "7")) + serial_settings.word_len = UART_7BITS_WORD; + else if (! grub_strcmp (state[3].arg, "8")) + serial_settings.word_len = UART_8BITS_WORD; + else + { + serial_settings = backup_settings; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length"); + } + } + + if (state[4].set) + { + if (! grub_strcmp (state[4].arg, "no")) + serial_settings.parity = UART_NO_PARITY; + else if (! grub_strcmp (state[4].arg, "odd")) + serial_settings.parity = UART_ODD_PARITY; + else if (! grub_strcmp (state[4].arg, "even")) + serial_settings.parity = UART_EVEN_PARITY; + else + { + serial_settings = backup_settings; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity"); + } + } + + if (state[5].set) + { + if (! grub_strcmp (state[5].arg, "1")) + serial_settings.stop_bits = UART_1_STOP_BIT; + else if (! grub_strcmp (state[5].arg, "2")) + serial_settings.stop_bits = UART_2_STOP_BITS; + else + { + serial_settings = backup_settings; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits"); + } + } + + /* Initialize with new settings. */ + hwiniterr = serial_hw_init (); + + if (hwiniterr == GRUB_ERR_NONE) + { + /* Register terminal if not yet registered. */ + if (registered == 0) + { + grub_term_register_input (&grub_serial_term_input); + grub_term_register_output (&grub_serial_term_output); + registered = 1; + } + } + else + { + /* Initialization with new settings failed. */ + if (registered == 1) + { + /* If the terminal is registered, attempt to restore previous + settings. */ + serial_settings = backup_settings; + if (serial_hw_init () != GRUB_ERR_NONE) + { + /* If unable to restore settings, unregister terminal. */ + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); + registered = 0; + } + } + } + + return hwiniterr; +} + +GRUB_MOD_INIT(serial) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("serial", grub_cmd_serial, GRUB_COMMAND_FLAG_BOTH, + "serial [OPTIONS...]", "Configure serial port.", options); + /* Set default settings. */ + serial_settings.port = serial_hw_get_port (0); + serial_settings.divisor = serial_get_divisor (9600); + serial_settings.word_len = UART_8BITS_WORD; + serial_settings.parity = UART_NO_PARITY; + serial_settings.stop_bits = UART_1_STOP_BIT; +} + +GRUB_MOD_FINI(serial) +{ + grub_unregister_command ("serial"); + if (registered == 1) /* Unregister terminal only if registered. */ + { + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); + } +} diff --git a/term/i386/pc/vesafb.c b/term/i386/pc/vesafb.c new file mode 100644 index 0000000..7305954 --- /dev/null +++ b/term/i386/pc/vesafb.c @@ -0,0 +1,609 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +// TODO: Deprecated and broken. Scheduled for removal as there is VBE driver in Video subsystem. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_CHAR_WIDTH 8 +#define DEFAULT_CHAR_HEIGHT 16 + +#define DEFAULT_FG_COLOR 0xa +#define DEFAULT_BG_COLOR 0x0 + +struct grub_colored_char +{ + /* An Unicode codepoint. */ + grub_uint32_t code; + + /* Color indexes. */ + unsigned char fg_color; + unsigned char bg_color; + + /* The width of this character minus one. */ + unsigned char width; + + /* The column index of this character. */ + unsigned char index; +}; + +struct grub_virtual_screen +{ + /* Dimensions of the virtual screen. */ + grub_uint32_t width; + grub_uint32_t height; + + /* Offset in the display. */ + grub_uint32_t offset_x; + grub_uint32_t offset_y; + + /* TTY Character sizes. */ + grub_uint32_t char_width; + grub_uint32_t char_height; + + /* Virtual screen TTY size. */ + grub_uint32_t columns; + grub_uint32_t rows; + + /* Current cursor details. */ + grub_uint32_t cursor_x; + grub_uint32_t cursor_y; + grub_uint8_t cursor_state; + grub_uint8_t fg_color; + grub_uint8_t bg_color; + + /* Text buffer for virtual screen. Contains (columns * rows) number + of entries. */ + struct grub_colored_char *text_buffer; +}; + +/* Make seure text buffer is not marked as allocated. */ +static struct grub_virtual_screen virtual_screen = + { + .text_buffer = 0 + }; + +static grub_dl_t my_mod; +static unsigned char *vga_font = 0; +static grub_uint32_t old_mode = 0; + +static struct grub_vbe_mode_info_block mode_info; +static grub_uint8_t *framebuffer = 0; +static grub_uint32_t bytes_per_scan_line = 0; + +static void +grub_virtual_screen_free (void) +{ + /* If virtual screen has been allocated, free it. */ + if (virtual_screen.text_buffer != 0) + grub_free (virtual_screen.text_buffer); + + /* Reset virtual screen data. */ + grub_memset (&virtual_screen, 0, sizeof (virtual_screen)); +} + +static grub_err_t +grub_virtual_screen_setup (grub_uint32_t width, + grub_uint32_t height) +{ + /* Free old virtual screen. */ + grub_virtual_screen_free (); + + /* Initialize with default data. */ + virtual_screen.width = width; + virtual_screen.height = height; + virtual_screen.offset_x = 0; + virtual_screen.offset_y = 0; + virtual_screen.char_width = DEFAULT_CHAR_WIDTH; + virtual_screen.char_height = DEFAULT_CHAR_HEIGHT; + virtual_screen.cursor_x = 0; + virtual_screen.cursor_y = 0; + virtual_screen.cursor_state = 1; + virtual_screen.fg_color = DEFAULT_FG_COLOR; + virtual_screen.bg_color = DEFAULT_BG_COLOR; + + /* Calculate size of text buffer. */ + virtual_screen.columns = virtual_screen.width / virtual_screen.char_width; + virtual_screen.rows = virtual_screen.height / virtual_screen.char_height; + + /* Allocate memory for text buffer. */ + virtual_screen.text_buffer = + (struct grub_colored_char *) grub_malloc (virtual_screen.columns + * virtual_screen.rows + * sizeof (*virtual_screen.text_buffer)); + + return grub_errno; +} + +static grub_err_t +grub_vesafb_mod_init (void) +{ + grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE; + struct grub_vbe_info_block controller_info; + char *modevar; + + /* Use fonts from VGA bios. */ + vga_font = grub_vga_get_font (); + + /* Check if we have VESA BIOS installed. */ + if (grub_vbe_probe (&controller_info) != GRUB_ERR_NONE) + return grub_errno; + + /* Check existence of vbe_mode environment variable. */ + modevar = grub_env_get ("vbe_mode"); + + if (modevar != 0) + { + unsigned long value; + + value = grub_strtoul (modevar, 0, 0); + if (grub_errno == GRUB_ERR_NONE) + use_mode = value; + } + + /* Store initial video mode. */ + if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE) + return grub_errno; + + /* Setup desired graphics mode. */ + if (grub_vbe_set_video_mode (use_mode, &mode_info) != GRUB_ERR_NONE) + return grub_errno; + + /* Determine framebuffer and bytes per scan line. */ + framebuffer = (grub_uint8_t *) mode_info.phys_base_addr; + + if (controller_info.version >= 0x300) + bytes_per_scan_line = mode_info.lin_bytes_per_scan_line; + else + bytes_per_scan_line = mode_info.bytes_per_scan_line; + + /* Create virtual screen. */ + if (grub_virtual_screen_setup (mode_info.x_resolution, + mode_info.y_resolution) != GRUB_ERR_NONE) + { + grub_vbe_set_video_mode (old_mode, 0); + return grub_errno; + } + + /* Make sure frame buffer is black. */ + grub_memset (framebuffer, + 0, + bytes_per_scan_line * mode_info.y_resolution); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_vesafb_mod_fini (void) +{ + grub_virtual_screen_free (); + + grub_vbe_set_video_mode (old_mode, 0); + + return GRUB_ERR_NONE; +} + +static int +grub_virtual_screen_get_glyph (grub_uint32_t code, + unsigned char bitmap[32], + unsigned *width) +{ + if (code > 0x7f) + { + /* Map some unicode characters to the VGA font, if possible. */ + switch (code) + { + case 0x2190: /* left arrow */ + code = 0x1b; + break; + case 0x2191: /* up arrow */ + code = 0x18; + break; + case 0x2192: /* right arrow */ + code = 0x1a; + break; + case 0x2193: /* down arrow */ + code = 0x19; + break; + case 0x2501: /* horizontal line */ + code = 0xc4; + break; + case 0x2503: /* vertical line */ + code = 0xb3; + break; + case 0x250F: /* upper-left corner */ + code = 0xda; + break; + case 0x2513: /* upper-right corner */ + code = 0xbf; + break; + case 0x2517: /* lower-left corner */ + code = 0xc0; + break; + case 0x251B: /* lower-right corner */ + code = 0xd9; + break; + + default: + return grub_font_get_glyph_any (code, bitmap, width); + } + } + + /* TODO This is wrong for the new font module. Should it be fixed? */ + if (bitmap) + grub_memcpy (bitmap, + vga_font + code * virtual_screen.char_height, + virtual_screen.char_height); + *width = 1; + return 1; +} + +static void +grub_virtual_screen_invalidate_char (struct grub_colored_char *p) +{ + p->code = 0xFFFF; + + if (p->width) + { + struct grub_colored_char *q; + + for (q = p + 1; q <= p + p->width; q++) + { + q->code = 0xFFFF; + q->width = 0; + q->index = 0; + } + } + + p->width = 0; +} + +static void +write_char (void) +{ + struct grub_colored_char *p; + unsigned char bitmap[32]; + unsigned width; + unsigned y; + unsigned offset; + + p = (virtual_screen.text_buffer + + virtual_screen.cursor_x + + (virtual_screen.cursor_y * virtual_screen.columns)); + + p -= p->index; + + if (! grub_virtual_screen_get_glyph (p->code, bitmap, &width)) + { + grub_virtual_screen_invalidate_char (p); + width = 0; + } + + for (y = 0, offset = 0; + y < virtual_screen.char_height; + y++, offset++) + { + unsigned i; + + for (i = 0; + (i < width * virtual_screen.char_width) && (offset < 32); + i++) + { + unsigned char color; + + if (bitmap[offset] & (1 << (8-i))) + { + color = p->fg_color; + } + else + { + color = p->bg_color; + } + + grub_vbe_set_pixel_index(i + (virtual_screen.cursor_x + * virtual_screen.char_width), + y + (virtual_screen.cursor_y + * virtual_screen.char_height), + color); + } + } +} + +static void +write_cursor (void) +{ + grub_uint32_t x; + grub_uint32_t y; + + for (y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3; + y < ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 1; + y++) + { + for (x = virtual_screen.cursor_x * virtual_screen.char_width; + x < (virtual_screen.cursor_x + 1) * virtual_screen.char_width; + x++) + { + grub_vbe_set_pixel_index(x, y, 10); + } + } +} + +static void +scroll_up (void) +{ + grub_uint32_t i; + + /* Scroll text buffer with one line to up. */ + grub_memmove (virtual_screen.text_buffer, + virtual_screen.text_buffer + virtual_screen.columns, + sizeof (*virtual_screen.text_buffer) + * virtual_screen.columns + * (virtual_screen.rows - 1)); + + /* Clear last line in text buffer. */ + for (i = virtual_screen.columns * (virtual_screen.rows - 1); + i < virtual_screen.columns * virtual_screen.rows; + i++) + { + virtual_screen.text_buffer[i].code = ' '; + virtual_screen.text_buffer[i].fg_color = 0; + virtual_screen.text_buffer[i].bg_color = 0; + virtual_screen.text_buffer[i].width = 0; + virtual_screen.text_buffer[i].index = 0; + } + + /* Scroll framebuffer with one line to up. */ + grub_memmove (framebuffer, + framebuffer + + bytes_per_scan_line * virtual_screen.char_height, + bytes_per_scan_line + * (mode_info.y_resolution - virtual_screen.char_height)); + + /* Clear last line in framebuffer. */ + grub_memset (framebuffer + + (bytes_per_scan_line + * (mode_info.y_resolution - virtual_screen.char_height)), + 0, + bytes_per_scan_line * virtual_screen.char_height); +} + +static void +grub_vesafb_putchar (grub_uint32_t c) +{ + if (c == '\a') + /* FIXME */ + return; + + if (c == '\b' || c == '\n' || c == '\r') + { + /* Erase current cursor, if any. */ + if (virtual_screen.cursor_state) + write_char (); + + switch (c) + { + case '\b': + if (virtual_screen.cursor_x > 0) + virtual_screen.cursor_x--; + break; + + case '\n': + if (virtual_screen.cursor_y >= virtual_screen.rows - 1) + scroll_up (); + else + virtual_screen.cursor_y++; + break; + + case '\r': + virtual_screen.cursor_x = 0; + break; + } + + if (virtual_screen.cursor_state) + write_cursor (); + } + else + { + unsigned width; + struct grub_colored_char *p; + + grub_virtual_screen_get_glyph (c, 0, &width); + + if (virtual_screen.cursor_x + width > virtual_screen.columns) + grub_putchar ('\n'); + + p = (virtual_screen.text_buffer + + virtual_screen.cursor_x + + virtual_screen.cursor_y * virtual_screen.columns); + p->code = c; + p->fg_color = virtual_screen.fg_color; + p->bg_color = virtual_screen.bg_color; + p->width = width - 1; + p->index = 0; + + if (width > 1) + { + unsigned i; + + for (i = 1; i < width; i++) + { + p[i].code = ' '; + p[i].width = width - 1; + p[i].index = i; + } + } + + write_char (); + + virtual_screen.cursor_x += width; + if (virtual_screen.cursor_x >= virtual_screen.columns) + { + virtual_screen.cursor_x = 0; + + if (virtual_screen.cursor_y >= virtual_screen.rows - 1) + scroll_up (); + else + virtual_screen.cursor_y++; + } + + if (virtual_screen.cursor_state) + write_cursor (); + } +} + +static grub_ssize_t +grub_vesafb_getcharwidth (grub_uint32_t c) +{ + unsigned width; + + if (! grub_virtual_screen_get_glyph (c, 0, &width)) + return 0; + + return width; +} + +static grub_uint16_t +grub_virtual_screen_getwh (void) +{ + return (virtual_screen.columns << 8) | virtual_screen.rows; +} + +static grub_uint16_t +grub_virtual_screen_getxy (void) +{ + return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y); +} + +static void +grub_vesafb_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + if (x >= virtual_screen.columns || y >= virtual_screen.rows) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", + (unsigned) x, (unsigned) y); + return; + } + + if (virtual_screen.cursor_state) + write_char (); + + virtual_screen.cursor_x = x; + virtual_screen.cursor_y = y; + + if (virtual_screen.cursor_state) + write_cursor (); +} + +static void +grub_virtual_screen_cls (void) +{ + grub_uint32_t i; + + for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) + { + virtual_screen.text_buffer[i].code = ' '; + virtual_screen.text_buffer[i].fg_color = 0; + virtual_screen.text_buffer[i].bg_color = 0; + virtual_screen.text_buffer[i].width = 0; + virtual_screen.text_buffer[i].index = 0; + } + + virtual_screen.cursor_x = virtual_screen.cursor_y = 0; +} + +static void +grub_vesafb_cls (void) +{ + grub_virtual_screen_cls (); + + grub_memset (framebuffer, + 0, + mode_info.y_resolution * bytes_per_scan_line); +} + +static void +grub_virtual_screen_setcolorstate (grub_term_color_state state) +{ + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + virtual_screen.fg_color = DEFAULT_FG_COLOR; + virtual_screen.bg_color = DEFAULT_BG_COLOR; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + virtual_screen.fg_color = DEFAULT_BG_COLOR; + virtual_screen.bg_color = DEFAULT_FG_COLOR; + break; + default: + break; + } +} + +static void +grub_vesafb_setcursor (int on) +{ + if (virtual_screen.cursor_state != on) + { + if (virtual_screen.cursor_state) + write_char (); + else + write_cursor (); + + virtual_screen.cursor_state = on; + } +} + +static struct grub_term_output grub_vesafb_term = + { + .name = "vesafb", + .init = grub_vesafb_mod_init, + .fini = grub_vesafb_mod_fini, + .putchar = grub_vesafb_putchar, + .getcharwidth = grub_vesafb_getcharwidth, + .getwh = grub_virtual_screen_getwh, + .getxy = grub_virtual_screen_getxy, + .gotoxy = grub_vesafb_gotoxy, + .cls = grub_vesafb_cls, + .setcolorstate = grub_virtual_screen_setcolorstate, + .setcursor = grub_vesafb_setcursor, + .flags = 0, + }; + +GRUB_MOD_INIT(vesafb) +{ + my_mod = mod; + grub_term_register_output (&grub_vesafb_term); +} + +GRUB_MOD_FINI(vesafb) +{ + grub_term_unregister_output (&grub_vesafb_term); +} diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c new file mode 100644 index 0000000..d32c86e --- /dev/null +++ b/term/i386/pc/vga.c @@ -0,0 +1,519 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +// TODO: Deprecated and broken. Needs to be converted to Video Driver! + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_VGA 0 + +#define VGA_WIDTH 640 +#define VGA_HEIGHT 350 +#define CHAR_WIDTH 8 +#define CHAR_HEIGHT 16 +#define TEXT_WIDTH (VGA_WIDTH / CHAR_WIDTH) +#define TEXT_HEIGHT (VGA_HEIGHT / CHAR_HEIGHT) +#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) +#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) + +#define DEFAULT_FG_COLOR 0xa +#define DEFAULT_BG_COLOR 0x0 + +struct colored_char +{ + /* An Unicode codepoint. */ + grub_uint32_t code; + + /* Color indexes. */ + unsigned char fg_color; + unsigned char bg_color; + + /* The width of this character minus one. */ + unsigned char width; + + /* The column index of this character. */ + unsigned char index; +}; + +static grub_dl_t my_mod; +static unsigned char text_mode; +static unsigned xpos, ypos; +static int cursor_state; +static unsigned char fg_color, bg_color; +static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT]; +static unsigned char saved_map_mask; +static int page = 0; +static grub_font_t font = 0; + +#define SEQUENCER_ADDR_PORT 0x3C4 +#define SEQUENCER_DATA_PORT 0x3C5 +#define MAP_MASK_REGISTER 0x02 + +#define CRTC_ADDR_PORT 0x3D4 +#define CRTC_DATA_PORT 0x3D5 +#define START_ADDR_HIGH_REGISTER 0x0C +#define START_ADDR_LOW_REGISTER 0x0D + +#define GRAPHICS_ADDR_PORT 0x3CE +#define GRAPHICS_DATA_PORT 0x3CF +#define READ_MAP_REGISTER 0x04 + +#define INPUT_STATUS1_REGISTER 0x3DA +#define INPUT_STATUS1_VERTR_BIT 0x08 + +static inline void +wait_vretrace (void) +{ + /* Wait until there is a vertical retrace. */ + while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT)); +} + +/* Get Map Mask Register. */ +static unsigned char +get_map_mask (void) +{ + unsigned char old_addr; + unsigned char old_data; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + old_data = grub_inb (SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); + + return old_data; +} + +/* Set Map Mask Register. */ +static void +set_map_mask (unsigned char mask) +{ + unsigned char old_addr; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + grub_outb (mask, SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); +} + +/* Set Read Map Register. */ +static void +set_read_map (unsigned char map) +{ + unsigned char old_addr; + + old_addr = grub_inb (GRAPHICS_ADDR_PORT); + + grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT); + grub_outb (map, GRAPHICS_DATA_PORT); + + grub_outb (old_addr, GRAPHICS_ADDR_PORT); +} + +/* Set start address. */ +static void +set_start_address (unsigned int start) +{ + unsigned char old_addr; + + old_addr = grub_inb (CRTC_ADDR_PORT); + + grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT); + grub_outb (start & 0xFF, CRTC_DATA_PORT); + + grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT); + grub_outb (start >> 8, CRTC_DATA_PORT); + + grub_outb (old_addr, CRTC_ADDR_PORT); +} + +static grub_err_t +grub_vga_mod_init (void) +{ + text_mode = grub_vga_set_mode (0x10); + cursor_state = 1; + fg_color = DEFAULT_FG_COLOR; + bg_color = DEFAULT_BG_COLOR; + saved_map_mask = get_map_mask (); + set_map_mask (0x0f); + set_start_address (PAGE_OFFSET (page)); + font = grub_font_get (""); /* Choose any font, for now. */ + if (!font) + return grub_error (GRUB_ERR_BAD_FONT, "No font loaded."); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_vga_mod_fini (void) +{ + set_map_mask (saved_map_mask); + grub_vga_set_mode (text_mode); + return GRUB_ERR_NONE; +} + +static int +check_vga_mem (void *p) +{ + return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page)) + && p <= (void *) (VGA_MEM + PAGE_OFFSET (page) + + VGA_WIDTH * VGA_HEIGHT / 8)); +} + +static void +write_char (void) +{ + struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH; + struct grub_font_glyph *glyph; + unsigned char *mem_base; + unsigned plane; + + mem_base = (VGA_MEM + xpos + + ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index; + p -= p->index; + + /* Get glyph for character. */ + glyph = grub_font_get_glyph (font, p->code); + + for (plane = 0x01; plane <= 0x08; plane <<= 1) + { + unsigned y; + unsigned offset; + unsigned char *mem; + + set_map_mask (plane); + + for (y = 0, offset = 0, mem = mem_base; + y < CHAR_HEIGHT; + y++, mem += TEXT_WIDTH) + { + /* TODO Re-implement glyph drawing for vga module. */ +#if 0 + unsigned i; + + unsigned char_width = 1; /* TODO Figure out wide characters. */ + for (i = 0; i < char_width && offset < 32; i++) + { + unsigned char fg_mask, bg_mask; + + fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0; + bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0; + offset++; + + if (check_vga_mem (mem + i)) + mem[i] = (fg_mask | bg_mask); + } +#endif /* 0 */ + } + } + + set_map_mask (0x0f); +} + +static void +write_cursor (void) +{ + unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos + + (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH); + if (check_vga_mem (mem)) + *mem = 0xff; + + mem += TEXT_WIDTH; + if (check_vga_mem (mem)) + *mem = 0xff; +} + +static void +scroll_up (void) +{ + unsigned i; + unsigned plane; + + /* Do all the work in the other page. */ + grub_memmove (text_buf, text_buf + TEXT_WIDTH, + sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1)); + + for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++) + { + text_buf[i].code = ' '; + text_buf[i].fg_color = 0; + text_buf[i].bg_color = 0; + text_buf[i].width = 0; + text_buf[i].index = 0; + } + + for (plane = 1; plane <= 4; plane++) + { + set_read_map (plane); + set_map_mask (1 << plane); + grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM + + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8, + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8); + } + + set_map_mask (0x0f); + grub_memset (VGA_MEM + PAGE_OFFSET (1 - page) + + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0, + VGA_WIDTH * CHAR_HEIGHT / 8); + + /* Activate the other page. */ + page = 1 - page; + wait_vretrace (); + set_start_address (PAGE_OFFSET (page)); +} + +static void +grub_vga_putchar (grub_uint32_t c) +{ +#if DEBUG_VGA + static int show = 1; +#endif + + if (c == '\a') + /* FIXME */ + return; + + if (c == '\b' || c == '\n' || c == '\r') + { + /* Erase current cursor, if any. */ + if (cursor_state) + write_char (); + + switch (c) + { + case '\b': + if (xpos > 0) + xpos--; + break; + + case '\n': + if (ypos >= TEXT_HEIGHT - 1) + scroll_up (); + else + ypos++; + break; + + case '\r': + xpos = 0; + break; + } + + if (cursor_state) + write_cursor (); + } + else + { + struct grub_font_glyph *glyph; + struct colored_char *p; + unsigned char_width = 1; + + glyph = grub_font_get_glyph(font, c); + + if (xpos + char_width > TEXT_WIDTH) + grub_putchar ('\n'); + + p = text_buf + xpos + ypos * TEXT_WIDTH; + p->code = c; + p->fg_color = fg_color; + p->bg_color = bg_color; + p->width = char_width - 1; + p->index = 0; + + if (char_width > 1) + { + unsigned i; + + for (i = 1; i < char_width; i++) + { + p[i].code = ' '; + p[i].width = char_width - 1; + p[i].index = i; + } + } + + write_char (); + + xpos += char_width; + if (xpos >= TEXT_WIDTH) + { + xpos = 0; + + if (ypos >= TEXT_HEIGHT - 1) + scroll_up (); + else + ypos++; + } + + if (cursor_state) + write_cursor (); + } + +#if DEBUG_VGA + if (show) + { + grub_uint16_t pos = grub_getxy (); + + show = 0; + grub_gotoxy (0, 0); + grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff)); + grub_gotoxy (pos >> 8, pos & 0xff); + show = 1; + } +#endif +} + +static grub_ssize_t +grub_vga_getcharwidth (grub_uint32_t c) +{ +#if 0 + struct grub_font_glyph glyph; + + glyph = grub_font_get_glyph (c); + + return glyph.char_width; +#else + (void) c; /* Prevent warning. */ + return 1; /* TODO Fix wide characters? */ +#endif +} + +static grub_uint16_t +grub_vga_getwh (void) +{ + return (TEXT_WIDTH << 8) | TEXT_HEIGHT; +} + +static grub_uint16_t +grub_vga_getxy (void) +{ + return ((xpos << 8) | ypos); +} + +static void +grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", + (unsigned) x, (unsigned) y); + return; + } + + if (cursor_state) + write_char (); + + xpos = x; + ypos = y; + + if (cursor_state) + write_cursor (); +} + +static void +grub_vga_cls (void) +{ + unsigned i; + + wait_vretrace (); + for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++) + { + text_buf[i].code = ' '; + text_buf[i].fg_color = 0; + text_buf[i].bg_color = 0; + text_buf[i].width = 0; + text_buf[i].index = 0; + } + + grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8); + + xpos = ypos = 0; +} + +static void +grub_vga_setcolorstate (grub_term_color_state state) +{ + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + fg_color = DEFAULT_FG_COLOR; + bg_color = DEFAULT_BG_COLOR; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + fg_color = DEFAULT_BG_COLOR; + bg_color = DEFAULT_FG_COLOR; + break; + default: + break; + } +} + +static void +grub_vga_setcursor (int on) +{ + if (cursor_state != on) + { + if (cursor_state) + write_char (); + else + write_cursor (); + + cursor_state = on; + } +} + +static struct grub_term_output grub_vga_term = + { + .name = "vga", + .init = grub_vga_mod_init, + .fini = grub_vga_mod_fini, + .putchar = grub_vga_putchar, + .getcharwidth = grub_vga_getcharwidth, + .getwh = grub_vga_getwh, + .getxy = grub_vga_getxy, + .gotoxy = grub_vga_gotoxy, + .cls = grub_vga_cls, + .setcolorstate = grub_vga_setcolorstate, + .setcursor = grub_vga_setcursor, + .flags = 0, + }; + +GRUB_MOD_INIT(vga) +{ +#ifndef GRUB_UTIL + my_mod = mod; +#endif + grub_term_register_output (&grub_vga_term); +} + +GRUB_MOD_FINI(vga) +{ + grub_term_unregister_output (&grub_vga_term); +} diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c new file mode 100644 index 0000000..e067ed6 --- /dev/null +++ b/term/i386/pc/vga_text.c @@ -0,0 +1,177 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007, 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +#define COLS 80 +#define ROWS 25 + +static int grub_curr_x, grub_curr_y; + +#define VGA_TEXT_SCREEN 0xb8000 + +#define CRTC_ADDR_PORT 0x3D4 +#define CRTC_DATA_PORT 0x3D5 + +#define CRTC_CURSOR 0x0a +#define CRTC_CURSOR_ADDR_HIGH 0x0e +#define CRTC_CURSOR_ADDR_LOW 0x0f + +#define CRTC_CURSOR_DISABLE (1 << 5) + +static void +screen_write_char (int x, int y, short c) +{ + ((short *) VGA_TEXT_SCREEN)[y * COLS + x] = c; +} + +static short +screen_read_char (int x, int y) +{ + return ((short *) VGA_TEXT_SCREEN)[y * COLS + x]; +} + +static void +update_cursor (void) +{ + unsigned int pos = grub_curr_y * COLS + grub_curr_x; + grub_outb (CRTC_CURSOR_ADDR_HIGH, CRTC_ADDR_PORT); + grub_outb (pos >> 8, CRTC_DATA_PORT); + grub_outb (CRTC_CURSOR_ADDR_LOW, CRTC_ADDR_PORT); + grub_outb (pos & 0xFF, CRTC_DATA_PORT); +} + +static void +inc_y (void) +{ + grub_curr_x = 0; + if (grub_curr_y < ROWS - 1) + grub_curr_y++; + else + { + int x, y; + for (y = 0; y < ROWS; y++) + for (x = 0; x < COLS; x++) + screen_write_char (x, y, screen_read_char (x, y + 1)); + } +} + +static void +inc_x (void) +{ + if (grub_curr_x >= COLS - 2) + inc_y (); + else + grub_curr_x++; +} + +void +grub_console_real_putchar (int c) +{ + switch (c) + { + case '\b': + if (grub_curr_x != 0) + screen_write_char (grub_curr_x--, grub_curr_y, ' '); + break; + case '\n': + inc_y (); + break; + case '\r': + grub_curr_x = 0; + break; + default: + screen_write_char (grub_curr_x, + grub_curr_y, c | (grub_console_cur_color << 8)); + inc_x (); + } + + update_cursor (); +} + +static grub_uint16_t +grub_vga_text_getxy (void) +{ + return (grub_curr_x << 8) | grub_curr_y; +} + +static void +grub_vga_text_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + grub_curr_x = x; + grub_curr_y = y; + update_cursor (); +} + +static void +grub_vga_text_cls (void) +{ + int i; + for (i = 0; i < ROWS * COLS; i++) + ((short *) VGA_TEXT_SCREEN)[i] = ' ' | (grub_console_cur_color << 8); + grub_vga_text_gotoxy (0, 0); +} + +static void +grub_vga_text_setcursor (int on) +{ + grub_uint8_t old; + grub_outb (CRTC_CURSOR, CRTC_ADDR_PORT); + old = grub_inb (CRTC_DATA_PORT); + if (on) + grub_outb (old & ~CRTC_CURSOR_DISABLE, CRTC_DATA_PORT); + else + grub_outb (old | CRTC_CURSOR_DISABLE, CRTC_DATA_PORT); +} + +static grub_err_t +grub_vga_text_init_fini (void) +{ + grub_vga_text_cls (); + return 0; +} + +static struct grub_term_output grub_vga_text_term = + { + .name = "vga_text", + .init = grub_vga_text_init_fini, + .fini = grub_vga_text_init_fini, + .putchar = grub_console_putchar, + .getcharwidth = grub_console_getcharwidth, + .getwh = grub_console_getwh, + .getxy = grub_vga_text_getxy, + .gotoxy = grub_vga_text_gotoxy, + .cls = grub_vga_text_cls, + .setcolorstate = grub_console_setcolorstate, + .setcolor = grub_console_setcolor, + .getcolor = grub_console_getcolor, + .setcursor = grub_vga_text_setcursor, + }; + +GRUB_MOD_INIT(vga_text) +{ + grub_term_register_output (&grub_vga_text_term); +} + +GRUB_MOD_FINI(vga_text) +{ + grub_term_unregister_output (&grub_vga_text_term); +} diff --git a/term/i386/vga_common.c b/term/i386/vga_common.c new file mode 100644 index 0000000..131b43a --- /dev/null +++ b/term/i386/vga_common.c @@ -0,0 +1,125 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +grub_uint8_t grub_console_cur_color = 0x7; +static grub_uint8_t grub_console_standard_color = 0x7; +static grub_uint8_t grub_console_normal_color = 0x7; +static grub_uint8_t grub_console_highlight_color = 0x70; + +static grub_uint32_t +map_char (grub_uint32_t c) +{ + if (c > 0x7f) + { + /* Map some unicode characters to the VGA font, if possible. */ + switch (c) + { + case 0x2190: /* left arrow */ + c = 0x1b; + break; + case 0x2191: /* up arrow */ + c = 0x18; + break; + case 0x2192: /* right arrow */ + c = 0x1a; + break; + case 0x2193: /* down arrow */ + c = 0x19; + break; + case 0x2501: /* horizontal line */ + c = 0xc4; + break; + case 0x2503: /* vertical line */ + c = 0xb3; + break; + case 0x250F: /* upper-left corner */ + c = 0xda; + break; + case 0x2513: /* upper-right corner */ + c = 0xbf; + break; + case 0x2517: /* lower-left corner */ + c = 0xc0; + break; + case 0x251B: /* lower-right corner */ + c = 0xd9; + break; + + default: + c = '?'; + break; + } + } + + return c; +} + +void +grub_console_putchar (grub_uint32_t c) +{ + grub_console_real_putchar (map_char (c)); +} + +grub_ssize_t +grub_console_getcharwidth (grub_uint32_t c __attribute__ ((unused))) +{ + /* For now, every printable character has the width 1. */ + return 1; +} + +grub_uint16_t +grub_console_getwh (void) +{ + return (80 << 8) | 25; +} + +void +grub_console_setcolorstate (grub_term_color_state state) +{ + switch (state) { + case GRUB_TERM_COLOR_STANDARD: + grub_console_cur_color = grub_console_standard_color; + break; + case GRUB_TERM_COLOR_NORMAL: + grub_console_cur_color = grub_console_normal_color; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + grub_console_cur_color = grub_console_highlight_color; + break; + default: + break; + } +} + +void +grub_console_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +{ + grub_console_normal_color = normal_color; + grub_console_highlight_color = highlight_color; +} + +void +grub_console_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +{ + *normal_color = grub_console_normal_color; + *highlight_color = grub_console_highlight_color; +} diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c new file mode 100644 index 0000000..70fda9a --- /dev/null +++ b/term/ieee1275/ofconsole.c @@ -0,0 +1,432 @@ +/* ofconsole.c -- Open Firmware console for GRUB. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_ieee1275_ihandle_t stdout_ihandle; +static grub_ieee1275_ihandle_t stdin_ihandle; + +static grub_uint8_t grub_ofconsole_width; +static grub_uint8_t grub_ofconsole_height; + +static int grub_curr_x; +static int grub_curr_y; + +static int grub_keybuf; +static int grub_buflen; + +struct color +{ + int red; + int green; + int blue; +}; + +#define MAX 0xff +static struct color colors[8] = + { + { 0, 0, 0}, + { MAX, 0, 0}, + { 0, MAX, 0}, + { MAX, MAX, 0}, + { 0, 0, MAX}, + { MAX, 0, MAX}, + { 0, MAX, MAX}, + { MAX, MAX, MAX} + }; + +static grub_uint8_t grub_ofconsole_normal_color = 0x7; +static grub_uint8_t grub_ofconsole_highlight_color = 0x70; + +/* Write control characters to the console. */ +static void +grub_ofconsole_writeesc (const char *str) +{ + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) + return; + + while (*str) + { + char chr = *(str++); + grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); + } + +} + +static void +grub_ofconsole_putchar (grub_uint32_t c) +{ + char chr = c; + if (c == '\n') + { + grub_curr_y++; + grub_curr_x = 0; + } + else + { + grub_curr_x++; + if (grub_curr_x > grub_ofconsole_width) + { + grub_putcode ('\n'); + grub_curr_x++; + } + } + grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); +} + +static grub_ssize_t +grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused))) +{ + return 1; +} + +static void +grub_ofconsole_setcolorstate (grub_term_color_state state) +{ + char setcol[20]; + int fg; + int bg; + + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: + fg = grub_ofconsole_normal_color & 0x0f; + bg = grub_ofconsole_normal_color >> 4; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + fg = grub_ofconsole_highlight_color & 0x0f; + bg = grub_ofconsole_highlight_color >> 4; + break; + default: + return; + } + + grub_sprintf (setcol, "\e[3%dm\e[4%dm", fg, bg); + grub_ofconsole_writeesc (setcol); +} + +static void +grub_ofconsole_setcolor (grub_uint8_t normal_color, + grub_uint8_t highlight_color) +{ + grub_ofconsole_normal_color = normal_color; + grub_ofconsole_highlight_color = highlight_color; +} + +static void +grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +{ + *normal_color = grub_ofconsole_normal_color; + *highlight_color = grub_ofconsole_highlight_color; +} + +static int +grub_ofconsole_readkey (int *key) +{ + char c; + grub_ssize_t actual = 0; + + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + if (actual > 0 && c == '\e') + { + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + if (actual <= 0) + { + *key = '\e'; + return 1; + } + + if (c != 91) + return 0; + + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + if (actual <= 0) + return 0; + + switch (c) + { + case 65: + /* Up: Ctrl-p. */ + c = 16; + break; + case 66: + /* Down: Ctrl-n. */ + c = 14; + break; + case 67: + /* Right: Ctrl-f. */ + c = 6; + break; + case 68: + /* Left: Ctrl-b. */ + c = 2; + break; + } + } + + *key = c; + return actual > 0; +} + +static int +grub_ofconsole_checkkey (void) +{ + int key; + int read; + + if (grub_buflen) + return 1; + + read = grub_ofconsole_readkey (&key); + if (read) + { + grub_keybuf = key; + grub_buflen = 1; + return 1; + } + + return -1; +} + +static int +grub_ofconsole_getkey (void) +{ + int key; + + if (grub_buflen) + { + grub_buflen =0; + return grub_keybuf; + } + + while (! grub_ofconsole_readkey (&key)); + + return key; +} + +static grub_uint16_t +grub_ofconsole_getxy (void) +{ + return ((grub_curr_x - 1) << 8) | grub_curr_y; +} + +static grub_uint16_t +grub_ofconsole_getwh (void) +{ + grub_ieee1275_ihandle_t options; + char *val; + grub_ssize_t lval; + + if (grub_ofconsole_width && grub_ofconsole_height) + return (grub_ofconsole_width << 8) | grub_ofconsole_height; + + if (! grub_ieee1275_finddevice ("/options", &options) + && options != (grub_ieee1275_ihandle_t) -1) + { + if (! grub_ieee1275_get_property_length (options, "screen-#columns", + &lval) && lval != -1) + { + val = grub_malloc (lval); + if (val) + { + if (! grub_ieee1275_get_property (options, "screen-#columns", + val, lval, 0)) + grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10); + + grub_free (val); + } + } + if (! grub_ieee1275_get_property_length (options, "screen-#rows", + &lval) && lval != -1) + { + val = grub_malloc (lval); + if (val) + { + if (! grub_ieee1275_get_property (options, "screen-#rows", + val, lval, 0)) + grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10); + + grub_free (val); + } + } + } + + /* Use a small console by default. */ + if (! grub_ofconsole_width) + grub_ofconsole_width = 80; + if (! grub_ofconsole_height) + grub_ofconsole_height = 24; + + return (grub_ofconsole_width << 8) | grub_ofconsole_height; +} + +static void +grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + char s[11]; /* 5 + 3 + 3. */ + + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) + { + grub_curr_x = x; + grub_curr_y = y; + + grub_sprintf (s, "\e[%d;%dH", y + 1, x + 1); + grub_ofconsole_writeesc (s); + } + else + { + if ((y == grub_curr_y) && (x == grub_curr_x - 1)) + { + char chr; + + chr = '\b'; + grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); + } + + grub_curr_x = x; + grub_curr_y = y; + } +} + +static void +grub_ofconsole_cls (void) +{ + /* Clear the screen. Using serial console, screen(1) only recognizes the + * ANSI escape sequence. Using video console, Apple Open Firmware (version + * 3.1.1) only recognizes the literal ^L. So use both. */ + grub_ofconsole_writeesc (" \e[2J"); + grub_gotoxy (0, 0); +} + +static void +grub_ofconsole_setcursor (int on) +{ + /* Understood by the Open Firmware flavour in OLPC. */ + if (on) + grub_ieee1275_interpret ("cursor-on", 0); + else + grub_ieee1275_interpret ("cursor-off", 0); +} + +static void +grub_ofconsole_refresh (void) +{ + /* Do nothing, the current console state is ok. */ +} + +static grub_err_t +grub_ofconsole_init_input (void) +{ + grub_ssize_t actual; + + if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle, + sizeof stdin_ihandle, &actual) + || actual != sizeof stdin_ihandle) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin"); + + return 0; +} + +static grub_err_t +grub_ofconsole_init_output (void) +{ + grub_ssize_t actual; + int col; + + /* The latest PowerMacs don't actually initialize the screen for us, so we + * use this trick to re-open the output device (but we avoid doing this on + * platforms where it's known to be broken). */ + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT)) + grub_ieee1275_interpret ("output-device output", 0); + + if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdout", &stdout_ihandle, + sizeof stdout_ihandle, &actual) + || actual != sizeof stdout_ihandle) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout"); + + /* Initialize colors. */ + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)) + { + for (col = 0; col < 7; col++) + grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red, + colors[col].green, colors[col].blue); + + /* Set the right fg and bg colors. */ + grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL); + } + + return 0; +} + +static grub_err_t +grub_ofconsole_fini (void) +{ + return 0; +} + + + +static struct grub_term_input grub_ofconsole_term_input = + { + .name = "ofconsole", + .init = grub_ofconsole_init_input, + .fini = grub_ofconsole_fini, + .checkkey = grub_ofconsole_checkkey, + .getkey = grub_ofconsole_getkey, + }; + +static struct grub_term_output grub_ofconsole_term_output = + { + .name = "ofconsole", + .init = grub_ofconsole_init_output, + .fini = grub_ofconsole_fini, + .putchar = grub_ofconsole_putchar, + .getcharwidth = grub_ofconsole_getcharwidth, + .getxy = grub_ofconsole_getxy, + .getwh = grub_ofconsole_getwh, + .gotoxy = grub_ofconsole_gotoxy, + .cls = grub_ofconsole_cls, + .setcolorstate = grub_ofconsole_setcolorstate, + .setcolor = grub_ofconsole_setcolor, + .getcolor = grub_ofconsole_getcolor, + .setcursor = grub_ofconsole_setcursor, + .refresh = grub_ofconsole_refresh, + .flags = 0, + }; + +void +grub_console_init (void) +{ + grub_term_register_input (&grub_ofconsole_term_input); + grub_term_register_output (&grub_ofconsole_term_output); +} + +void +grub_console_fini (void) +{ + grub_term_unregister_input (&grub_ofconsole_term_input); + grub_term_unregister_output (&grub_ofconsole_term_output); +} diff --git a/term/terminfo.c b/term/terminfo.c new file mode 100644 index 0000000..5cbbe16 --- /dev/null +++ b/term/terminfo.c @@ -0,0 +1,187 @@ +/* terminfo.c - simple terminfo module */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* + * This file contains various functions dealing with different + * terminal capabilities. For example, vt52 and vt100. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct terminfo +{ + char *name; + + char *gotoxy; + char *cls; + char *reverse_video_on; + char *reverse_video_off; + char *cursor_on; + char *cursor_off; +}; + +static struct terminfo term; + +/* Get current terminfo name. */ +char * +grub_terminfo_get_current (void) +{ + return term.name; +} + +/* Free *PTR and set *PTR to NULL, to prevent double-free. */ +static void +grub_terminfo_free (char **ptr) +{ + grub_free (*ptr); + *ptr = 0; +} + +/* Set current terminfo type. */ +grub_err_t +grub_terminfo_set_current (const char *str) +{ + /* TODO + * Lookup user specified terminfo type. If found, set term variables + * as appropriate. Otherwise return an error. + * + * How should this be done? + * a. A static table included in this module. + * - I do not like this idea. + * b. A table stored in the configuration directory. + * - Users must convert their terminfo settings if we have not already. + * c. Look for terminfo files in the configuration directory. + * - /usr/share/terminfo is 6.3M on my system. + * - /usr/share/terminfo is not on most users boot partition. + * + Copying the terminfo files you want to use to the grub + * configuration directory is easier then (b). + * d. Your idea here. + */ + + /* Free previously allocated memory. */ + grub_terminfo_free (&term.name); + grub_terminfo_free (&term.gotoxy); + grub_terminfo_free (&term.cls); + grub_terminfo_free (&term.reverse_video_on); + grub_terminfo_free (&term.reverse_video_off); + grub_terminfo_free (&term.cursor_on); + grub_terminfo_free (&term.cursor_off); + + if (grub_strcmp ("vt100", str) == 0) + { + term.name = grub_strdup ("vt100"); + term.gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); + term.cls = grub_strdup ("\e[H\e[J"); + term.reverse_video_on = grub_strdup ("\e[7m"); + term.reverse_video_off = grub_strdup ("\e[m"); + term.cursor_on = grub_strdup ("\e[?25h"); + term.cursor_off = grub_strdup ("\e[?25l"); + return grub_errno; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type."); +} + +/* Wrapper for grub_putchar to write strings. */ +static void +putstr (const char *str) +{ + while (*str) + grub_putchar (*str++); +} + +/* Move the cursor to the given position starting with "0". */ +void +grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + putstr (grub_terminfo_tparm (term.gotoxy, y, x)); +} + +/* Clear the screen. */ +void +grub_terminfo_cls (void) +{ + putstr (grub_terminfo_tparm (term.cls)); +} + +/* Set reverse video mode on. */ +void +grub_terminfo_reverse_video_on (void) +{ + putstr (grub_terminfo_tparm (term.reverse_video_on)); +} + +/* Set reverse video mode off. */ +void +grub_terminfo_reverse_video_off (void) +{ + putstr (grub_terminfo_tparm (term.reverse_video_off)); +} + +/* Show cursor. */ +void +grub_terminfo_cursor_on (void) +{ + putstr (grub_terminfo_tparm (term.cursor_on)); +} + +/* Hide cursor. */ +void +grub_terminfo_cursor_off (void) +{ + putstr (grub_terminfo_tparm (term.cursor_off)); +} + +/* GRUB Command. */ + +static grub_err_t +grub_cmd_terminfo (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + if (argc == 0) + { + grub_printf ("Current terminfo type: %s\n", grub_terminfo_get_current()); + return GRUB_ERR_NONE; + } + else if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters."); + else + return grub_terminfo_set_current (args[0]); +} + +GRUB_MOD_INIT(terminfo) +{ + (void) mod; /* To stop warning. */ + grub_register_command ("terminfo", grub_cmd_terminfo, GRUB_COMMAND_FLAG_BOTH, + "terminfo [TERM]", "Set terminfo type.", 0); + grub_terminfo_set_current ("vt100"); +} + +GRUB_MOD_FINI(terminfo) +{ + grub_unregister_command ("terminfo"); +} diff --git a/term/tparm.c b/term/tparm.c new file mode 100644 index 0000000..b634dba --- /dev/null +++ b/term/tparm.c @@ -0,0 +1,768 @@ +/**************************************************************************** + * Copyright (c) 1998-2003,2004,2005 Free Software Foundation, Inc. * + * * + * 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, distribute with modifications, 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 ABOVE 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. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/********************************************************************** + * This code is a modification of lib_tparm.c found in ncurses-5.2. The + * modification are for use in grub by replacing all libc function through + * special grub functions. This also meant to delete all dynamic memory + * allocation and replace it by a number of fixed buffers. + * + * Modifications by Tilmann Bubeck 2002 + * + * Resync with ncurses-5.4 by Omniflux 2005 + **********************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + * and: Thomas E. Dickey, 1996 on * + ****************************************************************************/ + +/* + * tparm.c + * + */ + +#include +#include +#include +#include + +/* + * Common/troublesome character definitions + */ +typedef char grub_bool_t; +#ifndef FALSE +# define FALSE (0) +#endif +#ifndef TRUE +# define TRUE (!FALSE) +#endif + +#define NUM_PARM 9 +#define NUM_VARS 26 +#define STACKSIZE 20 +#define MAX_FORMAT_LEN 256 + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define isdigit(c) ((c) >= '0' && (c) <= '9') +#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define isLOWER(c) ((c) >= 'a' && (c) <= 'z') + +#define UChar(c) ((unsigned char)(c)) + +//MODULE_ID("$Id: tparm.c 1665 2008-07-02 00:54:18Z proski $") + +/* + * char * + * tparm(string, ...) + * + * Substitute the given parameters into the given string by the following + * rules (taken from terminfo(5)): + * + * Cursor addressing and other strings requiring parame- + * ters in the terminal are described by a parameterized string + * capability, with like escapes %x in it. For example, to + * address the cursor, the cup capability is given, using two + * parameters: the row and column to address to. (Rows and + * columns are numbered from zero and refer to the physical + * screen visible to the user, not to any unseen memory.) If + * the terminal has memory relative cursor addressing, that can + * be indicated by + * + * The parameter mechanism uses a stack and special % + * codes to manipulate it. Typically a sequence will push one + * of the parameters onto the stack and then print it in some + * format. Often more complex operations are necessary. + * + * The % encodings have the following meanings: + * + * %% outputs `%' + * %c print pop() like %c in printf() + * %s print pop() like %s in printf() + * %[[:]flags][width[.precision]][doxXs] + * as in printf, flags are [-+#] and space + * The ':' is used to avoid making %+ or %- + * patterns (see below). + * + * %p[1-9] push ith parm + * %P[a-z] set dynamic variable [a-z] to pop() + * %g[a-z] get dynamic variable [a-z] and push it + * %P[A-Z] set static variable [A-Z] to pop() + * %g[A-Z] get static variable [A-Z] and push it + * %l push strlen(pop) + * %'c' push char constant c + * %{nn} push integer constant nn + * + * %+ %- %* %/ %m + * arithmetic (%m is mod): push(pop() op pop()) + * %& %| %^ bit operations: push(pop() op pop()) + * %= %> %< logical operations: push(pop() op pop()) + * %A %O logical and & or operations for conditionals + * %! %~ unary operations push(op pop()) + * %i add 1 to first two parms (for ANSI terminals) + * + * %? expr %t thenpart %e elsepart %; + * if-then-else, %e elsepart is optional. + * else-if's are possible ala Algol 68: + * %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %; + * + * For those of the above operators which are binary and not commutative, + * the stack works in the usual way, with + * %gx %gy %m + * resulting in x mod y, not the reverse. + */ + +typedef struct { + union { + int num; + char *str; + } data; + grub_bool_t num_type; +} stack_frame; + +static stack_frame stack[STACKSIZE]; +static int stack_ptr; +static const char *tparam_base = ""; + +static char *out_buff; +static grub_size_t out_size; +static grub_size_t out_used; + +static char *fmt_buff; +static grub_size_t fmt_size; + +static inline void +get_space(grub_size_t need) +{ + need += out_used; + if (need > out_size) { + out_size = need * 2; + out_buff = grub_realloc(out_buff, out_size*sizeof(char)); + /* FIX ME! handle out_buff == 0. */ + } +} + +static inline void +save_text(const char *fmt, const char *s, int len) +{ + grub_size_t s_len = grub_strlen(s); + if (len > (int) s_len) + s_len = len; + + get_space(s_len + 1); + + (void) grub_sprintf(out_buff + out_used, fmt, s); + out_used += grub_strlen(out_buff + out_used); +} + +static inline void +save_number(const char *fmt, int number, int len) +{ + if (len < 30) + len = 30; /* actually log10(MAX_INT)+1 */ + + get_space((unsigned) len + 1); + + (void) grub_sprintf(out_buff + out_used, fmt, number); + out_used += grub_strlen(out_buff + out_used); +} + +static inline void +save_char(int c) +{ + if (c == 0) + c = 0200; + get_space(1); + out_buff[out_used++] = c; +} + +static inline void +npush(int x) +{ + if (stack_ptr < STACKSIZE) { + stack[stack_ptr].num_type = TRUE; + stack[stack_ptr].data.num = x; + stack_ptr++; + } +} + +static inline int +npop(void) +{ + int result = 0; + if (stack_ptr > 0) { + stack_ptr--; + if (stack[stack_ptr].num_type) + result = stack[stack_ptr].data.num; + } + return result; +} + +static inline void +spush(char *x) +{ + if (stack_ptr < STACKSIZE) { + stack[stack_ptr].num_type = FALSE; + stack[stack_ptr].data.str = x; + stack_ptr++; + } +} + +static inline char * +spop(void) +{ + static char dummy[] = ""; /* avoid const-cast */ + char *result = dummy; + if (stack_ptr > 0) { + stack_ptr--; + if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0) + result = stack[stack_ptr].data.str; + } + return result; +} + +static inline const char * +parse_format(const char *s, char *format, int *len) +{ + *len = 0; + if (format != 0) { + grub_bool_t done = FALSE; + grub_bool_t allowminus = FALSE; + grub_bool_t dot = FALSE; + grub_bool_t err = FALSE; + char *fmt = format; + int my_width = 0; + int my_prec = 0; + int value = 0; + + *len = 0; + *format++ = '%'; + while (*s != '\0' && !done) { + switch (*s) { + case 'c': /* FALLTHRU */ + case 'd': /* FALLTHRU */ + case 'o': /* FALLTHRU */ + case 'x': /* FALLTHRU */ + case 'X': /* FALLTHRU */ + case 's': + *format++ = *s; + done = TRUE; + break; + case '.': + *format++ = *s++; + if (dot) { + err = TRUE; + } else { /* value before '.' is the width */ + dot = TRUE; + my_width = value; + } + value = 0; + break; + case '#': + *format++ = *s++; + break; + case ' ': + *format++ = *s++; + break; + case ':': + s++; + allowminus = TRUE; + break; + case '-': + if (allowminus) { + *format++ = *s++; + } else { + done = TRUE; + } + break; + default: + if (isdigit(UChar(*s))) { + value = (value * 10) + (*s - '0'); + if (value > 10000) + err = TRUE; + *format++ = *s++; + } else { + done = TRUE; + } + } + } + + /* + * If we found an error, ignore (and remove) the flags. + */ + if (err) { + my_width = my_prec = value = 0; + format = fmt; + *format++ = '%'; + *format++ = *s; + } + + /* + * Any value after '.' is the precision. If we did not see '.', then + * the value is the width. + */ + if (dot) + my_prec = value; + else + my_width = value; + + *format = '\0'; + /* return maximum string length in print */ + *len = (my_width > my_prec) ? my_width : my_prec; + } + return s; +} + +/* + * Analyze the string to see how many parameters we need from the varargs list, + * and what their types are. We will only accept string parameters if they + * appear as a %l or %s format following an explicit parameter reference (e.g., + * %p2%s). All other parameters are numbers. + * + * 'number' counts coarsely the number of pop's we see in the string, and + * 'popcount' shows the highest parameter number in the string. We would like + * to simply use the latter count, but if we are reading termcap strings, there + * may be cases that we cannot see the explicit parameter numbers. + */ +static inline int +analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount) +{ + grub_size_t len2; + int i; + int lastpop = -1; + int len; + int number = 0; + const char *cp = string; + static char dummy[] = ""; + + *popcount = 0; + + if (cp == 0) + return 0; + + if ((len2 = grub_strlen(cp)) > fmt_size) { + fmt_size = len2 + fmt_size + 2; + if ((fmt_buff = grub_realloc(fmt_buff, fmt_size*sizeof(char))) == 0) + return 0; + } + + grub_memset(p_is_s, 0, sizeof(p_is_s[0]) * NUM_PARM); + + while ((cp - string) < (int) len2) { + if (*cp == '%') { + cp++; + cp = parse_format(cp, fmt_buff, &len); + switch (*cp) { + default: + break; + + case 'd': /* FALLTHRU */ + case 'o': /* FALLTHRU */ + case 'x': /* FALLTHRU */ + case 'X': /* FALLTHRU */ + case 'c': /* FALLTHRU */ + if (lastpop <= 0) + number++; + lastpop = -1; + break; + + case 'l': + case 's': + if (lastpop > 0) + p_is_s[lastpop - 1] = dummy; + ++number; + break; + + case 'p': + cp++; + i = (UChar(*cp) - '0'); + if (i >= 0 && i <= NUM_PARM) { + lastpop = i; + if (lastpop > *popcount) + *popcount = lastpop; + } + break; + + case 'P': + ++number; + ++cp; + break; + + case 'g': + cp++; + break; + + case '\'': + cp += 2; + lastpop = -1; + break; + + case '{': + cp++; + while (isdigit(UChar(*cp))) { + cp++; + } + break; + + case '+': + case '-': + case '*': + case '/': + case 'm': + case 'A': + case 'O': + case '&': + case '|': + case '^': + case '=': + case '<': + case '>': + lastpop = -1; + number += 2; + break; + + case '!': + case '~': + lastpop = -1; + ++number; + break; + + case 'i': + /* will add 1 to first (usually two) parameters */ + break; + } + } + if (*cp != '\0') + cp++; + } + + if (number > NUM_PARM) + number = NUM_PARM; + return number; +} + +static inline char * +tparam_internal(const char *string, va_list ap) +{ + char *p_is_s[NUM_PARM]; + long param[NUM_PARM]; + int popcount; + int number; + int len; + int level; + int x, y; + int i; + const char *cp = string; + grub_size_t len2; + static int dynamic_var[NUM_VARS]; + static int static_vars[NUM_VARS]; + + if (cp == 0) + return 0; + + out_used = out_size = fmt_size = 0; + + len2 = (int) grub_strlen(cp); + + /* + * Find the highest parameter-number referred to in the format string. + * Use this value to limit the number of arguments copied from the + * variable-length argument list. + */ + number = analyze(cp, p_is_s, &popcount); + if (fmt_buff == 0) + return 0; + + for (i = 0; i < max(popcount, number); i++) { + /* + * A few caps (such as plab_norm) have string-valued parms. + * We'll have to assume that the caller knows the difference, since + * a char* and an int may not be the same size on the stack. + */ + if (p_is_s[i] != 0) { + p_is_s[i] = va_arg(ap, char *); + } else { + param[i] = va_arg(ap, long int); + } + } + + /* + * This is a termcap compatibility hack. If there are no explicit pop + * operations in the string, load the stack in such a way that + * successive pops will grab successive parameters. That will make + * the expansion of (for example) \E[%d;%dH work correctly in termcap + * style, which means tparam() will expand termcap strings OK. + */ + stack_ptr = 0; + if (popcount == 0) { + popcount = number; + for (i = number - 1; i >= 0; i--) + npush(param[i]); + } + + while ((cp - string) < (int) len2) { + if (*cp != '%') { + save_char(UChar(*cp)); + } else { + tparam_base = cp++; + cp = parse_format(cp, fmt_buff, &len); + switch (*cp) { + default: + break; + case '%': + save_char('%'); + break; + + case 'd': /* FALLTHRU */ + case 'o': /* FALLTHRU */ + case 'x': /* FALLTHRU */ + case 'X': /* FALLTHRU */ + save_number(fmt_buff, npop(), len); + break; + + case 'c': /* FALLTHRU */ + save_char(npop()); + break; + + case 'l': + save_number("%d", (int) grub_strlen(spop()), 0); + break; + + case 's': + save_text(fmt_buff, spop(), len); + break; + + case 'p': + cp++; + i = (UChar(*cp) - '1'); + if (i >= 0 && i < NUM_PARM) { + if (p_is_s[i]) + spush(p_is_s[i]); + else + npush(param[i]); + } + break; + + case 'P': + cp++; + if (isUPPER(*cp)) { + i = (UChar(*cp) - 'A'); + static_vars[i] = npop(); + } else if (isLOWER(*cp)) { + i = (UChar(*cp) - 'a'); + dynamic_var[i] = npop(); + } + break; + + case 'g': + cp++; + if (isUPPER(*cp)) { + i = (UChar(*cp) - 'A'); + npush(static_vars[i]); + } else if (isLOWER(*cp)) { + i = (UChar(*cp) - 'a'); + npush(dynamic_var[i]); + } + break; + + case '\'': + cp++; + npush(UChar(*cp)); + cp++; + break; + + case '{': + number = 0; + cp++; + while (isdigit(UChar(*cp))) { + number = (number * 10) + (UChar(*cp) - '0'); + cp++; + } + npush(number); + break; + + case '+': + npush(npop() + npop()); + break; + + case '-': + y = npop(); + x = npop(); + npush(x - y); + break; + + case '*': + npush(npop() * npop()); + break; + + case '/': + y = npop(); + x = npop(); + npush(y ? (x / y) : 0); + break; + + case 'm': + y = npop(); + x = npop(); + npush(y ? (x % y) : 0); + break; + + case 'A': + npush(npop() && npop()); + break; + + case 'O': + npush(npop() || npop()); + break; + + case '&': + npush(npop() & npop()); + break; + + case '|': + npush(npop() | npop()); + break; + + case '^': + npush(npop() ^ npop()); + break; + + case '=': + y = npop(); + x = npop(); + npush(x == y); + break; + + case '<': + y = npop(); + x = npop(); + npush(x < y); + break; + + case '>': + y = npop(); + x = npop(); + npush(x > y); + break; + + case '!': + npush(!npop()); + break; + + case '~': + npush(~npop()); + break; + + case 'i': + if (p_is_s[0] == 0) + param[0]++; + if (p_is_s[1] == 0) + param[1]++; + break; + + case '?': + break; + + case 't': + x = npop(); + if (!x) { + /* scan forward for %e or %; at level zero */ + cp++; + level = 0; + while (*cp) { + if (*cp == '%') { + cp++; + if (*cp == '?') + level++; + else if (*cp == ';') { + if (level > 0) + level--; + else + break; + } else if (*cp == 'e' && level == 0) + break; + } + + if (*cp) + cp++; + } + } + break; + + case 'e': + /* scan forward for a %; at level zero */ + cp++; + level = 0; + while (*cp) { + if (*cp == '%') { + cp++; + if (*cp == '?') + level++; + else if (*cp == ';') { + if (level > 0) + level--; + else + break; + } + } + + if (*cp) + cp++; + } + break; + + case ';': + break; + + } /* endswitch (*cp) */ + } /* endelse (*cp == '%') */ + + if (*cp == '\0') + break; + + cp++; + } /* endwhile (*cp) */ + + get_space(1); + out_buff[out_used] = '\0'; + + return (out_buff); +} + +char * +grub_terminfo_tparm (const char *string, ...) +{ + va_list ap; + char *result; + + va_start (ap, string); + result = tparam_internal (string, ap); + va_end (ap); + return result; +} diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c new file mode 100644 index 0000000..07f7d08 --- /dev/null +++ b/term/usb_keyboard.c @@ -0,0 +1,257 @@ +/* Support for the HID Boot Protocol. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static char keyboard_map[128] = + { + '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', + '3', '4', '5', '6', '7', '8', '9', '0', + '\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[', + ']', '\\', '#', ';', '\'', '`', ',', '.', + '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT, + GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP + }; + +static char keyboard_map_shift[128] = + { + '\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', + '#', '$', '%', '^', '&', '*', '(', ')', + '\n', '\0', '\0', '\0', ' ', '_', '+', '{', + '}', '|', '#', ':', '"', '`', '<', '>', + '?' + }; + +static grub_usb_device_t usbdev; + +static void +grub_usb_hid (void) +{ + struct grub_usb_desc_device *descdev; + + auto int usb_iterate (grub_usb_device_t dev); + int usb_iterate (grub_usb_device_t dev) + { + descdev = &dev->descdev; + + grub_dprintf ("usb_keyboard", "%x %x %x\n", + descdev->class, descdev->subclass, descdev->protocol); + +#if 0 + if (descdev->class != 0x09 + || descdev->subclass == 0x01 + || descdev->protocol != 0x02) + return 0; +#endif + + if (descdev->class != 0 || descdev->subclass != 0 || descdev->protocol != 0) + return 0; + + grub_printf ("HID found!\n"); + + usbdev = dev; + + return 1; + } + grub_usb_iterate (usb_iterate); + + /* Place the device in boot mode. */ + grub_usb_control_msg (usbdev, 0x21, 0x0B, 0, 0, 0, 0); + + /* Reports everytime an event occurs and not more often than that. */ + grub_usb_control_msg (usbdev, 0x21, 0x0A, 0<<8, 0, 0, 0); +} + +static grub_err_t +grub_usb_keyboard_getreport (grub_usb_device_t dev, unsigned char *report) +{ + return grub_usb_control_msg (dev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0, + 8, (char *) report); +} + + + +static int +grub_usb_keyboard_checkkey (void) +{ + unsigned char data[8]; + int key; + int i; + grub_err_t err; + + data[2] = 0; + for (i = 0; i < 50; i++) + { + /* Get_Report. */ + err = grub_usb_keyboard_getreport (usbdev, data); + + if (! err && data[2]) + break; + } + + if (err || !data[2]) + return -1; + + grub_dprintf ("usb_keyboard", + "report: 0x%02x 0x%02x 0x%02x 0x%02x" + " 0x%02x 0x%02x 0x%02x 0x%02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + + /* Check if the Control or Shift key was pressed. */ + if (data[0] & 0x01 || data[0] & 0x10) + key = keyboard_map[data[2]] - 'a' + 1; + else if (data[0] & 0x02 || data[0] & 0x20) + key = keyboard_map_shift[data[2]]; + else + key = keyboard_map[data[2]]; + + if (key == 0) + grub_printf ("Unknown key 0x%x detected\n", data[2]); + +#if 0 + /* Wait until the key is released. */ + while (!err && data[2]) + { + err = grub_usb_control_msg (usbdev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0, + sizeof (data), (char *) data); + grub_dprintf ("usb_keyboard", + "report2: 0x%02x 0x%02x 0x%02x 0x%02x" + " 0x%02x 0x%02x 0x%02x 0x%02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); + } +#endif + + grub_errno = GRUB_ERR_NONE; + + return key; +} + +typedef enum +{ + GRUB_HIDBOOT_REPEAT_NONE, + GRUB_HIDBOOT_REPEAT_FIRST, + GRUB_HIDBOOT_REPEAT +} grub_usb_keyboard_repeat_t; + +static int +grub_usb_keyboard_getkey (void) +{ + int key; + int key_release; + grub_err_t err; + unsigned char data[8]; + grub_uint64_t currtime; + int timeout; + static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE; + + again: + + do + { + key = grub_usb_keyboard_checkkey (); + } while (key == -1); + + data[2] = !0; /* Or whatever. */ + err = 0; + + switch (repeat) + { + case GRUB_HIDBOOT_REPEAT_NONE: + timeout = 100; + break; + case GRUB_HIDBOOT_REPEAT_FIRST: + timeout = 500; + break; + case GRUB_HIDBOOT_REPEAT: + timeout = 50; + break; + } + + /* Wait until the key is released. */ + currtime = grub_get_time_ms (); + while (!err && data[2]) + { + /* Implement a timeout. */ + if (grub_get_time_ms () > currtime + timeout) + { + if (repeat == 0) + repeat = 1; + else + repeat = 2; + + grub_errno = GRUB_ERR_NONE; + return key; + } + + err = grub_usb_keyboard_getreport (usbdev, data); + } + + if (repeat) + { + repeat = 0; + goto again; + } + + repeat = 0; + + grub_errno = GRUB_ERR_NONE; + + return key; +} + +static struct grub_term_input grub_usb_keyboard_term = + { + .name = "usb_keyboard", + .checkkey = grub_usb_keyboard_checkkey, + .getkey = grub_usb_keyboard_getkey, + .next = 0 + }; + +GRUB_MOD_INIT(usb_keyboard) +{ + (void) mod; /* To stop warning. */ + + grub_usb_hid (); + grub_term_register_input (&grub_usb_keyboard_term); +} + +GRUB_MOD_FINI(usb_keyboard) +{ + grub_term_unregister_input (&grub_usb_keyboard_term); +} diff --git a/util/console.c b/util/console.c new file mode 100644 index 0000000..718afc1 --- /dev/null +++ b/util/console.c @@ -0,0 +1,387 @@ +/* console.c -- Ncurses console for GRUB. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#if defined(HAVE_NCURSES_CURSES_H) +# include +#elif defined(HAVE_NCURSES_H) +# include +#elif defined(HAVE_CURSES_H) +# include +#endif + +/* For compatibility. */ +#ifndef A_NORMAL +# define A_NORMAL 0 +#endif /* ! A_NORMAL */ +#ifndef A_STANDOUT +# define A_STANDOUT 0 +#endif /* ! A_STANDOUT */ + +#include +#include +#include + +static int grub_console_attr = A_NORMAL; + +grub_uint8_t grub_console_cur_color = 7; + +static grub_uint8_t grub_console_standard_color = 0x7; +static grub_uint8_t grub_console_normal_color = 0x7; +static grub_uint8_t grub_console_highlight_color = 0x70; + +#define NUM_COLORS 8 + +static grub_uint8_t color_map[NUM_COLORS] = +{ + COLOR_BLACK, + COLOR_BLUE, + COLOR_GREEN, + COLOR_CYAN, + COLOR_RED, + COLOR_MAGENTA, + COLOR_YELLOW, + COLOR_WHITE +}; + +static int use_color; + +static void +grub_ncurses_putchar (grub_uint32_t c) +{ + /* Better than nothing. */ + switch (c) + { + case GRUB_TERM_DISP_LEFT: + c = '<'; + break; + + case GRUB_TERM_DISP_UP: + c = '^'; + break; + + case GRUB_TERM_DISP_RIGHT: + c = '>'; + break; + + case GRUB_TERM_DISP_DOWN: + c = 'v'; + break; + + case GRUB_TERM_DISP_HLINE: + c = '-'; + break; + + case GRUB_TERM_DISP_VLINE: + c = '|'; + break; + + case GRUB_TERM_DISP_UL: + case GRUB_TERM_DISP_UR: + case GRUB_TERM_DISP_LL: + case GRUB_TERM_DISP_LR: + c = '+'; + break; + + default: + /* ncurses does not support Unicode. */ + if (c > 0x7f) + c = '?'; + break; + } + + addch (c | grub_console_attr); +} + +static grub_ssize_t +grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused))) +{ + return 1; +} + +static void +grub_ncurses_setcolorstate (grub_term_color_state state) +{ + switch (state) + { + case GRUB_TERM_COLOR_STANDARD: + grub_console_cur_color = grub_console_standard_color; + grub_console_attr = A_NORMAL; + break; + case GRUB_TERM_COLOR_NORMAL: + grub_console_cur_color = grub_console_normal_color; + grub_console_attr = A_NORMAL; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: + grub_console_cur_color = grub_console_highlight_color; + grub_console_attr = A_STANDOUT; + break; + default: + break; + } + + if (use_color) + { + grub_uint8_t fg, bg; + + fg = (grub_console_cur_color & 7); + bg = (grub_console_cur_color >> 4) & 7; + + grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL; + color_set ((bg << 3) + fg, 0); + } +} + +/* XXX: This function is never called. */ +static void +grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) +{ + grub_console_normal_color = normal_color; + grub_console_highlight_color = highlight_color; +} + +static void +grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +{ + *normal_color = grub_console_normal_color; + *highlight_color = grub_console_highlight_color; +} + +static int saved_char = ERR; + +static int +grub_ncurses_checkkey (void) +{ + int c; + + /* Check for SAVED_CHAR. This should not be true, because this + means checkkey is called twice continuously. */ + if (saved_char != ERR) + return saved_char; + + wtimeout (stdscr, 100); + c = getch (); + /* If C is not ERR, then put it back in the input queue. */ + if (c != ERR) + { + saved_char = c; + return c; + } + + return -1; +} + +static int +grub_ncurses_getkey (void) +{ + int c; + + /* If checkkey has already got a character, then return it. */ + if (saved_char != ERR) + { + c = saved_char; + saved_char = ERR; + } + else + { + wtimeout (stdscr, -1); + c = getch (); + } + + switch (c) + { + case KEY_LEFT: + c = 2; + break; + + case KEY_RIGHT: + c = 6; + break; + + case KEY_UP: + c = 16; + break; + + case KEY_DOWN: + c = 14; + break; + + case KEY_IC: + c = 24; + break; + + case KEY_DC: + c = 4; + break; + + case KEY_BACKSPACE: + /* XXX: For some reason ncurses on xterm does not return + KEY_BACKSPACE. */ + case 127: + c = 8; + break; + + case KEY_HOME: + c = 1; + break; + + case KEY_END: + c = 5; + break; + + case KEY_NPAGE: + c = 3; + break; + + case KEY_PPAGE: + c = 7; + break; + } + + return c; +} + +static grub_uint16_t +grub_ncurses_getxy (void) +{ + int x; + int y; + + getyx (stdscr, y, x); + + return (x << 8) | y; +} + +static grub_uint16_t +grub_ncurses_getwh (void) +{ + int x; + int y; + + getmaxyx (stdscr, y, x); + + return (x << 8) | y; +} + +static void +grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y) +{ + move (y, x); +} + +static void +grub_ncurses_cls (void) +{ + clear (); + refresh (); +} + +static void +grub_ncurses_setcursor (int on) +{ + curs_set (on ? 1 : 0); +} + +static void +grub_ncurses_refresh (void) +{ + refresh (); +} + +static grub_err_t +grub_ncurses_init (void) +{ + initscr (); + raw (); + noecho (); + scrollok (stdscr, TRUE); + + nonl (); + intrflush (stdscr, FALSE); + keypad (stdscr, TRUE); + + if (has_colors ()) + { + start_color (); + + if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS)) + { + int i, j, n; + + n = 0; + for (i = 0; i < NUM_COLORS; i++) + for (j = 0; j < NUM_COLORS; j++) + init_pair(n++, color_map[j], color_map[i]); + + use_color = 1; + } + } + + return 0; +} + +static grub_err_t +grub_ncurses_fini (void) +{ + endwin (); + return 0; +} + + +static struct grub_term_input grub_ncurses_term_input = + { + .name = "console", + .checkkey = grub_ncurses_checkkey, + .getkey = grub_ncurses_getkey, + }; + +static struct grub_term_output grub_ncurses_term_output = + { + .name = "console", + .init = grub_ncurses_init, + .fini = grub_ncurses_fini, + .putchar = grub_ncurses_putchar, + .getcharwidth = grub_ncurses_getcharwidth, + .getxy = grub_ncurses_getxy, + .getwh = grub_ncurses_getwh, + .gotoxy = grub_ncurses_gotoxy, + .cls = grub_ncurses_cls, + .setcolorstate = grub_ncurses_setcolorstate, + .setcolor = grub_ncurses_setcolor, + .getcolor = grub_ncurses_getcolor, + .setcursor = grub_ncurses_setcursor, + .refresh = grub_ncurses_refresh, + .flags = 0, + }; + +void +grub_console_init (void) +{ + grub_term_register_output (&grub_ncurses_term_output); + grub_term_register_input (&grub_ncurses_term_input); + grub_term_set_current_output (&grub_ncurses_term_output); + grub_term_set_current_input (&grub_ncurses_term_input); +} + +void +grub_console_fini (void) +{ + grub_ncurses_fini (); +} diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c new file mode 100644 index 0000000..f841035 --- /dev/null +++ b/util/elf/grub-mkimage.c @@ -0,0 +1,425 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_hdr +{ + grub_uint32_t namesz; + grub_uint32_t descsz; + grub_uint32_t type; + char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; +}; + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +struct grub_ieee1275_note +{ + struct grub_ieee1275_note_hdr header; + struct grub_ieee1275_note_desc descriptor; +}; + +void +load_note (Elf32_Phdr *phdr, FILE *out) +{ + struct grub_ieee1275_note note; + int note_size = sizeof (struct grub_ieee1275_note); + + grub_util_info ("adding CHRP NOTE segment"); + + note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note.header.descsz = grub_host_to_target32 (note_size); + note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME); + note.descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note.descriptor.real_base = grub_host_to_target32 (0x00c00000); + note.descriptor.real_size = grub_host_to_target32 (0xffffffff); + note.descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note.descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note.descriptor.load_base = grub_host_to_target32 (0x00004000); + + /* Write the note data to the new segment. */ + grub_util_write_image_at (¬e, note_size, + grub_target_to_host32 (phdr->p_offset), out); + + /* Fill in the rest of the segment header. */ + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; +} + +void +load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, + char *mods[], FILE *out, char *memdisk_path) +{ + char *module_img; + struct grub_util_path_list *path_list; + struct grub_util_path_list *p; + struct grub_module_info *modinfo; + size_t offset; + size_t total_module_size; + size_t memdisk_size = 0; + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + offset = sizeof (struct grub_module_info); + total_module_size = sizeof (struct grub_module_info); + + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); + grub_util_info ("the size of memory disk is 0x%x", memdisk_size); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + for (p = path_list; p; p = p->next) + { + total_module_size += (grub_util_get_image_size (p->name) + + sizeof (struct grub_module_header)); + } + + grub_util_info ("the total module size is 0x%x", total_module_size); + + module_img = xmalloc (total_module_size); + modinfo = (struct grub_module_info *) module_img; + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info)); + modinfo->size = grub_host_to_target32 (total_module_size); + + /* Load all the modules, with headers, into module_img. */ + for (p = path_list; p; p = p->next) + { + struct grub_module_header *header; + size_t mod_size; + + grub_util_info ("adding module %s", p->name); + + mod_size = grub_util_get_image_size (p->name); + + header = (struct grub_module_header *) (module_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); + header->size = grub_host_to_target32 (mod_size + sizeof (*header)); + + grub_util_load_image (p->name, module_img + offset + sizeof (*header)); + + offset += sizeof (*header) + mod_size; + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (module_img + offset); + header->type = grub_cpu_to_le32 (OBJ_TYPE_MEMDISK); + header->size = grub_cpu_to_le32 (memdisk_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (memdisk_path, module_img + offset); + offset += memdisk_size; + } + + + /* Write the module data to the new segment. */ + grub_util_write_image_at (module_img, total_module_size, + grub_host_to_target32 (phdr->p_offset), out); + + /* Fill in the rest of the segment header. */ + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr->p_vaddr = grub_host_to_target32 (modbase); + phdr->p_paddr = grub_host_to_target32 (modbase); + phdr->p_filesz = grub_host_to_target32 (total_module_size); + phdr->p_memsz = grub_host_to_target32 (total_module_size); +} + +void +add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path) +{ + Elf32_Ehdr ehdr; + Elf32_Phdr *phdrs = NULL; + Elf32_Phdr *phdr; + FILE *in; + char *kernel_path; + grub_addr_t grub_end = 0; + off_t offset, first_segment; + int i, phdr_size; + + /* Read ELF header. */ + kernel_path = grub_util_get_path (dir, "kernel.elf"); + in = fopen (kernel_path, "rb"); + if (! in) + grub_util_error ("cannot open %s", kernel_path); + + grub_util_read_at (&ehdr, sizeof (ehdr), 0, in); + + offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG); + ehdr.e_phoff = grub_host_to_target32 (offset); + + phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) * + grub_target_to_host16 (ehdr.e_phnum)); + + if (mods[0] != NULL) + phdr_size += grub_target_to_host16 (ehdr.e_phentsize); + + if (chrp) + phdr_size += grub_target_to_host16 (ehdr.e_phentsize); + + phdrs = xmalloc (phdr_size); + offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG); + + first_segment = offset; + + /* Copy all existing segments. */ + for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++) + { + char *segment_img; + grub_size_t segment_end; + + phdr = phdrs + i; + + /* Read segment header. */ + grub_util_read_at (phdr, sizeof (Elf32_Phdr), + (grub_target_to_host32 (ehdr.e_phoff) + + (i * grub_target_to_host16 (ehdr.e_phentsize))), + in); + grub_util_info ("copying segment %d, type %d", i, + grub_target_to_host32 (phdr->p_type)); + + /* Locate _end. */ + segment_end = grub_target_to_host32 (phdr->p_paddr) + + grub_target_to_host32 (phdr->p_memsz); + grub_util_info ("segment %u end 0x%lx", i, segment_end); + if (segment_end > grub_end) + grub_end = segment_end; + + /* Read segment data and write it to new file. */ + segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz)); + + grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz), + grub_target_to_host32 (phdr->p_offset), in); + + phdr->p_offset = grub_host_to_target32 (offset); + grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz), + offset, out); + offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz), + GRUB_TARGET_SIZEOF_LONG); + + free (segment_img); + } + + if (mods[0] != NULL) + { + grub_addr_t modbase; + + /* Place modules just after grub segment. */ + modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); + + /* Construct new segment header for modules. */ + phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); + ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); + + /* Fill in p_offset so the callees know where to write. */ + phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), + GRUB_TARGET_SIZEOF_LONG)); + + load_modules (modbase, phdr, dir, mods, out, memdisk_path); + } + + if (chrp) + { + /* Construct new segment header for the CHRP note. */ + phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); + ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); + + /* Fill in p_offset so the callees know where to write. */ + phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), + GRUB_TARGET_SIZEOF_LONG)); + + load_note (phdr, out); + } + + /* Don't bother preserving the section headers. */ + ehdr.e_shoff = 0; + ehdr.e_shnum = 0; + ehdr.e_shstrndx = 0; + + /* Write entire segment table to the file. */ + grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out); + + /* Write ELF header. */ + grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out); + + if (prefix) + { + if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) + grub_util_error ("prefix too long"); + grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); + } + + free (phdrs); + free (kernel_path); +} + +static struct option options[] = + { + {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, + {"memdisk", required_argument, 0, 'm'}, + {"output", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {"note", no_argument, 0, 'n'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + { 0, 0, 0, 0 }, + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n"); + else + printf ("\ +Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\ +\n\ +Make a bootable image of GRUB.\n\ +\n\ +-d, --directory=DIR use images and modules under DIR [default=%s]\n\ +-p, --prefix=DIR set grub_prefix directory\n\ +-m, --memdisk=FILE embed FILE as a memdisk image\n\ +-o, --output=FILE output a generated image to FILE\n\ +-h, --help display this message and exit\n\ +-n, --note add NOTE segment for CHRP Open Firmware\n\ +-V, --version print version information and exit\n\ +-v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", GRUB_LIBDIR, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + FILE *fp; + char *output = NULL; + char *dir = NULL; + char *prefix = NULL; + char *memdisk = NULL; + int chrp = 0; + + progname = "grub-mkimage"; + + while (1) + { + int c = getopt_long (argc, argv, "d:p:m:o:hVvn", options, 0); + if (c == -1) + break; + + switch (c) + { + case 'd': + if (dir) + free (dir); + dir = xstrdup (optarg); + break; + case 'p': + if (prefix) + free (prefix); + prefix = xstrdup (optarg); + break; + case 'm': + if (memdisk) + free (memdisk); + memdisk = xstrdup (optarg); + + if (prefix) + free (prefix); + prefix = xstrdup ("(memdisk)/boot/grub"); + + break; + case 'h': + usage (0); + break; + case 'n': + chrp = 1; + break; + case 'o': + if (output) + free (output); + output = xstrdup (optarg); + break; + case 'V': + printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + case 'v': + verbosity++; + break; + default: + usage (1); + break; + } + } + + if (!output) + usage (1); + + fp = fopen (output, "wb"); + if (! fp) + grub_util_error ("cannot open %s", output); + + add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk); + + fclose (fp); + + return 0; +} diff --git a/util/getroot.c b/util/getroot.c new file mode 100644 index 0000000..e88354e --- /dev/null +++ b/util/getroot.c @@ -0,0 +1,521 @@ +/* getroot.c - Get root device */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#ifdef __CYGWIN__ +# include +# include +# include +# define DEV_CYGDRIVE_MAJOR 98 +#endif + +#include +#include +#include + +static void +strip_extra_slashes (char *dir) +{ + char *p = dir; + + while ((p = strchr (p, '/')) != 0) + { + if (p[1] == '/') + { + memmove (p, p + 1, strlen (p)); + continue; + } + else if (p[1] == '\0') + { + if (p > dir) + p[0] = '\0'; + break; + } + + p++; + } +} + +static char * +xgetcwd (void) +{ + size_t size = 10; + char *path; + + path = xmalloc (size); + while (! getcwd (path, size)) + { + size <<= 1; + path = xrealloc (path, size); + } + + return path; +} + +#ifdef __CYGWIN__ +/* Convert POSIX path to Win32 path, + remove drive letter, replace backslashes. */ +static char * +get_win32_path (const char *path) +{ + char winpath[PATH_MAX]; + cygwin_conv_to_full_win32_path (path, winpath); + + int len = strlen (winpath); + if (len > 2 && winpath[1] == ':') + { + len -= 2; + memmove (winpath, winpath + 2, len + 1); + } + + int i; + for (i = 0; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath); +} +#endif + +char * +grub_get_prefix (const char *dir) +{ + char *saved_cwd; + char *abs_dir, *prev_dir; + char *prefix; + struct stat st, prev_st; + + /* Save the current directory. */ + saved_cwd = xgetcwd (); + + if (chdir (dir) < 0) + grub_util_error ("Cannot change directory to `%s'", dir); + + abs_dir = xgetcwd (); + strip_extra_slashes (abs_dir); + prev_dir = xstrdup (abs_dir); + + if (stat (".", &prev_st) < 0) + grub_util_error ("Cannot stat `%s'", dir); + + if (! S_ISDIR (prev_st.st_mode)) + grub_util_error ("`%s' is not a directory", dir); + + while (1) + { + if (chdir ("..") < 0) + grub_util_error ("Cannot change directory to the parent"); + + if (stat (".", &st) < 0) + grub_util_error ("Cannot stat current directory"); + + if (! S_ISDIR (st.st_mode)) + grub_util_error ("Current directory is not a directory???"); + + if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino) + break; + + free (prev_dir); + prev_dir = xgetcwd (); + prev_st = st; + } + + strip_extra_slashes (prev_dir); + prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2); + prefix[0] = '/'; + strcpy (prefix + 1, abs_dir + strlen (prev_dir)); + strip_extra_slashes (prefix); + + if (chdir (saved_cwd) < 0) + grub_util_error ("Cannot change directory to `%s'", dir); + +#ifdef __CYGWIN__ + if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) + { + /* Reached some mount point not below /cygdrive. + GRUB does not know Cygwin's emulated mounts, + convert to Win32 path. */ + grub_util_info ("Cygwin prefix = %s", prefix); + char * wprefix = get_win32_path (prefix); + free (prefix); + prefix = wprefix; + } +#endif + + free (saved_cwd); + free (abs_dir); + free (prev_dir); + + grub_util_info ("prefix = %s", prefix); + return prefix; +} + +#ifdef __MINGW32__ + +static char * +find_root_device (const char *dir __attribute__ ((unused)), + dev_t dev __attribute__ ((unused))) +{ + return 0; +} + +#elif ! defined(__CYGWIN__) + +static char * +find_root_device (const char *dir, dev_t dev) +{ + DIR *dp; + char *saved_cwd; + struct dirent *ent; + + dp = opendir (dir); + if (! dp) + return 0; + + saved_cwd = xgetcwd (); + + grub_util_info ("changing current directory to %s", dir); + if (chdir (dir) < 0) + { + free (saved_cwd); + closedir (dp); + return 0; + } + + while ((ent = readdir (dp)) != 0) + { + struct stat st; + + /* Avoid: + - dotfiles (like "/dev/.tmp.md0") since they could be duplicates. + - dotdirs (like "/dev/.static") since they could contain duplicates. */ + if (ent->d_name[0] == '.') + continue; + + if (lstat (ent->d_name, &st) < 0) + /* Ignore any error. */ + continue; + + if (S_ISLNK (st.st_mode)) + /* Don't follow symbolic links. */ + continue; + + if (S_ISDIR (st.st_mode)) + { + /* Find it recursively. */ + char *res; + + res = find_root_device (ent->d_name, dev); + + if (res) + { + if (chdir (saved_cwd) < 0) + grub_util_error ("Cannot restore the original directory"); + + free (saved_cwd); + closedir (dp); + return res; + } + } + + if (S_ISBLK (st.st_mode) && st.st_rdev == dev) + { +#ifdef __linux__ + /* Skip device names like /dev/dm-0, which are short-hand aliases + to more descriptive device names, e.g. those under /dev/mapper */ + if (ent->d_name[0] == 'd' && + ent->d_name[1] == 'm' && + ent->d_name[2] == '-' && + ent->d_name[3] >= '0' && + ent->d_name[3] <= '9') + continue; +#endif + + /* Found! */ + char *res; + char *cwd; + + cwd = xgetcwd (); + res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2); + sprintf (res, "%s/%s", cwd, ent->d_name); + strip_extra_slashes (res); + free (cwd); + + /* /dev/root is not a real block device keep looking, takes care + of situation where root filesystem is on the same partition as + grub files */ + + if (strcmp(res, "/dev/root") == 0) + continue; + + if (chdir (saved_cwd) < 0) + grub_util_error ("Cannot restore the original directory"); + + free (saved_cwd); + closedir (dp); + return res; + } + } + + if (chdir (saved_cwd) < 0) + grub_util_error ("Cannot restore the original directory"); + + free (saved_cwd); + closedir (dp); + return 0; +} + +#else /* __CYGWIN__ */ + +/* Read drive/partition serial number from mbr/boot sector, + return 0 on read error, ~0 on unknown serial. */ +static unsigned +get_bootsec_serial (const char *os_dev, int mbr) +{ + /* Read boot sector. */ + int fd = open (os_dev, O_RDONLY); + if (fd < 0) + return 0; + unsigned char buf[0x200]; + int n = read (fd, buf, sizeof (buf)); + close (fd); + if (n != sizeof(buf)) + return 0; + + /* Check signature. */ + if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa)) + return ~0; + + /* Serial number offset depends on boot sector type. */ + if (mbr) + n = 0x1b8; + else if (memcmp (buf + 0x03, "NTFS", 4) == 0) + n = 0x048; + else if (memcmp (buf + 0x52, "FAT32", 5) == 0) + n = 0x043; + else if (memcmp (buf + 0x36, "FAT", 3) == 0) + n = 0x027; + else + return ~0; + + unsigned serial = *(unsigned *)(buf + n); + if (serial == 0) + return ~0; + return serial; +} + +static char * +find_cygwin_root_device (const char *path, dev_t dev) +{ + /* No root device for /cygdrive. */ + if (dev == (DEV_CYGDRIVE_MAJOR << 16)) + return 0; + + /* Convert to full POSIX and Win32 path. */ + char fullpath[PATH_MAX], winpath[PATH_MAX]; + cygwin_conv_to_full_posix_path (path, fullpath); + cygwin_conv_to_full_win32_path (fullpath, winpath); + + /* If identical, this is no real filesystem path. */ + if (strcmp (fullpath, winpath) == 0) + return 0; + + /* Check for floppy drive letter. */ + if (winpath[0] && winpath[1] == ':' && strchr ("AaBb", winpath[0])) + return xstrdup (strchr ("Aa", winpath[0]) ? "/dev/fd0" : "/dev/fd1"); + + /* Cygwin returns the partition serial number in stat.st_dev. + This is never identical to the device number of the emulated + /dev/sdXN device, so above find_root_device () does not work. + Search the partion with the same serial in boot sector instead. */ + char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */ + int d; + for (d = 'a'; d <= 'z'; d++) + { + sprintf (devpath, "/dev/sd%c", d); + if (get_bootsec_serial (devpath, 1) == 0) + continue; + int p; + for (p = 1; p <= 15; p++) + { + sprintf (devpath, "/dev/sd%c%d", d, p); + unsigned ser = get_bootsec_serial (devpath, 0); + if (ser == 0) + break; + if (ser != (unsigned)~0 && dev == (dev_t)ser) + return xstrdup (devpath); + } + } + return 0; +} + +#endif /* __CYGWIN__ */ + +char * +grub_guess_root_device (const char *dir) +{ + struct stat st; + char *os_dev; + + if (stat (dir, &st) < 0) + grub_util_error ("Cannot stat `%s'", dir); + +#ifdef __CYGWIN__ + /* Cygwin specific function. */ + os_dev = find_cygwin_root_device (dir, st.st_dev); + +#else + + /* This might be truly slow, but is there any better way? */ + os_dev = find_root_device ("/dev", st.st_dev); +#endif + + return os_dev; +} + +int +grub_util_get_dev_abstraction (const char *os_dev) +{ +#ifdef __linux__ + /* Check for LVM. */ + if (!strncmp (os_dev, "/dev/mapper/", 12)) + return GRUB_DEV_ABSTRACTION_LVM; + + /* Check for RAID. */ + if (!strncmp (os_dev, "/dev/md", 7)) + return GRUB_DEV_ABSTRACTION_RAID; +#endif + + /* No abstraction found. */ + return GRUB_DEV_ABSTRACTION_NONE; +} + +char * +grub_util_get_grub_dev (const char *os_dev) +{ + char *grub_dev; + + switch (grub_util_get_dev_abstraction (os_dev)) + { + case GRUB_DEV_ABSTRACTION_LVM: + + { + unsigned short i, len; + grub_size_t offset = sizeof ("/dev/mapper/") - 1; + + len = strlen (os_dev) - offset + 1; + grub_dev = xmalloc (len); + + for (i = 0; i < len; i++, offset++) + { + grub_dev[i] = os_dev[offset]; + if (os_dev[offset] == '-' && os_dev[offset + 1] == '-') + offset++; + } + } + + break; + + case GRUB_DEV_ABSTRACTION_RAID: + + if (os_dev[7] == '_' && os_dev[8] == 'd') + { + /* This a partitionable RAID device of the form /dev/md_dNNpMM. */ + + char *p, *q; + + p = strdup (os_dev + sizeof ("/dev/md_d") - 1); + + q = strchr (p, 'p'); + if (q) + *q = ','; + + asprintf (&grub_dev, "md%s", p); + free (p); + } + else if (os_dev[7] == '/' && os_dev[8] == 'd') + { + /* This a partitionable RAID device of the form /dev/md/dNNpMM. */ + + char *p, *q; + + p = strdup (os_dev + sizeof ("/dev/md/d") - 1); + + q = strchr (p, 'p'); + if (q) + *q = ','; + + asprintf (&grub_dev, "md%s", p); + free (p); + } + else if (os_dev[7] >= '0' && os_dev[7] <= '9') + { + char *p , *q; + + p = strdup (os_dev + sizeof ("/dev/md") - 1); + + q = strchr (p, 'p'); + if (q) + *q = ','; + + asprintf (&grub_dev, "md%s", p); + free (p); + } + else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9') + { + char *p , *q; + + p = strdup (os_dev + sizeof ("/dev/md/") - 1); + + q = strchr (p, 'p'); + if (q) + *q = ','; + + asprintf (&grub_dev, "md%s", p); + free (p); + } + else + grub_util_error ("Unknown kind of RAID device `%s'", os_dev); + + break; + + default: /* GRUB_DEV_ABSTRACTION_NONE */ + grub_dev = grub_util_biosdisk_get_grub_dev (os_dev); + } + + return grub_dev; +} + +const char * +grub_util_check_block_device (const char *blk_dev) +{ + struct stat st; + + if (stat (blk_dev, &st) < 0) + grub_util_error ("Cannot stat `%s'", blk_dev); + + if (S_ISBLK (st.st_mode)) + return (blk_dev); + else + return 0; +} diff --git a/util/grub-editenv.c b/util/grub-editenv.c new file mode 100644 index 0000000..475d12d --- /dev/null +++ b/util/grub-editenv.c @@ -0,0 +1,269 @@ +/* grub-editenv.c - tool to edit environment block. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +void +grub_putchar (int c) +{ + putchar (c); +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +void * +grub_term_get_current_input (void) +{ + return 0; +} + +void * +grub_term_get_current_output (void) +{ + return 0; +} + +int +grub_getkey (void) +{ + return 0; +} + +char * +grub_env_get (const char *name __attribute__ ((unused))) +{ + return NULL; +} + +static struct option options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +char buffer[GRUB_ENVBLK_MAXLEN]; +grub_envblk_t envblk; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n"); + else + printf ("\ +Usage: grub-editenv [OPTIONS] FILENAME COMMAND\n\ +\n\ +Tool to edit environment block.\n\ +\nCommands:\n\ + create create a blank environment block file\n\ + info show information about the environment block\n\ + list list the current variables\n\ + set [name=value] ... change/delete variables\n\ + clear delete all variables\n\ +\nOptions:\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n", PACKAGE_BUGREPORT); + + exit (status); +} + +int +create_envblk_file (char *name) +{ + FILE *f; + grub_envblk_t p; + + f = fopen (name, "wb"); + if (! f) + return 1; + + /* Just in case OS don't save 0s. */ + memset (buffer, -1, sizeof (buffer)); + + p = (grub_envblk_t) &buffer[0]; + p->signature = GRUB_ENVBLK_SIGNATURE; + p->length = sizeof (buffer) - sizeof (struct grub_envblk); + p->data[0] = p->data[1] = 0; + + fwrite (buffer, sizeof (buffer), 1, f); + + fclose (f); + return 0; +} + +FILE * +open_envblk_file (char *name) +{ + FILE *f; + + f = fopen (name, "r+b"); + if (! f) + grub_util_error ("Can\'t open file %s", name); + + if (fread (buffer, 1, sizeof (buffer), f) != sizeof (buffer)) + grub_util_error ("The envblk file is too short"); + + envblk = grub_envblk_find (buffer); + if (! envblk) + grub_util_error ("Can\'t find environment block"); + + return f; +} + +static void +cmd_info (void) +{ + printf ("Envblk offset: %ld\n", (long) (envblk->data - buffer)); + printf ("Envblk length: %d\n", envblk->length); +} + +static void +cmd_list (void) +{ + auto int hook (char *name, char *value); + int hook (char *name, char *value) + { + printf ("%s=%s\n", name, value); + return 0; + } + + grub_envblk_iterate (envblk, hook); +} + +static void +cmd_set (int argc, char *argv[]) +{ + while (argc) + { + char *p; + + p = strchr (argv[0], '='); + if (! p) + grub_util_error ("Invalid parameter"); + + *(p++) = 0; + + if (*p) + { + if (grub_envblk_insert (envblk, argv[0], p)) + grub_util_error ("Environment block too small"); + } + else + grub_envblk_delete (envblk, argv[0]); + + argc--; + argv++; + } +} + +static void +cmd_clear (void) +{ + envblk->data[0] = envblk->data[1] = 0; +} + +int +main (int argc, char *argv[]) +{ + FILE *f; + + progname = "grub-editenv"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + /* Obtain PATH. */ + if (optind >= argc) + { + fprintf (stderr, "Filename not specified.\n"); + usage (1); + } + + if (optind + 1 >= argc) + { + fprintf (stderr, "Command not specified.\n"); + usage (1); + } + + if (! strcmp (argv[optind + 1], "create")) + return create_envblk_file (argv[optind]); + + f = open_envblk_file (argv[optind]); + + optind++; + if (! strcmp (argv[optind], "info")) + cmd_info (); + else if (! strcmp (argv[optind], "list")) + cmd_list (); + else + { + if (! strcmp (argv[optind], "set")) + cmd_set (argc - optind - 1, argv + optind + 1); + else if (! strcmp (argv[optind], "clear")) + cmd_clear (); + + fseeko (f, 0, SEEK_SET); + fwrite (buffer, sizeof (buffer), 1, f); + } + fclose (f); + + return 0; +} diff --git a/util/grub-emu.c b/util/grub-emu.c new file mode 100644 index 0000000..59392fe --- /dev/null +++ b/util/grub-emu.c @@ -0,0 +1,226 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Used for going back to the main function. */ +jmp_buf main_env; + +/* Store the prefix specified by an argument. */ +static char *prefix = 0; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return 0; +} + +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + (void) ehdr; + + return GRUB_ERR_BAD_MODULE; +} + +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + (void) mod; + (void) ehdr; + + return GRUB_ERR_BAD_MODULE; +} + +void +grub_machine_init (void) +{ +} + +void +grub_machine_set_prefix (void) +{ + grub_env_set ("prefix", prefix); + free (prefix); + prefix = 0; +} + +void +grub_machine_fini (void) +{ + grub_console_fini (); +} + + +static struct option options[] = + { + {"root-device", required_argument, 0, 'r'}, + {"device-map", required_argument, 0, 'm'}, + {"directory", required_argument, 0, 'd'}, + {"hold", optional_argument, 0, 'H'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + { 0, 0, 0, 0 } + }; + +static int +usage (int status) +{ + if (status) + fprintf (stderr, + "Try ``grub-emu --help'' for more information.\n"); + else + printf ( + "Usage: grub-emu [OPTION]...\n" + "\n" + "GRUB emulator.\n" + "\n" + " -r, --root-device=DEV use DEV as the root device [default=guessed]\n" + " -m, --device-map=FILE use FILE as the device map [default=%s]\n" + " -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n" + " -v, --verbose print verbose messages\n" + " -H, --hold[=SECONDS] wait until a debugger will attach\n" + " -h, --help display this message and exit\n" + " -V, --version print version information and exit\n" + "\n" + "Report bugs to <%s>.\n", DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); + return status; +} + + +int +main (int argc, char *argv[]) +{ + char *root_dev = 0; + char *dir = DEFAULT_DIRECTORY; + char *dev_map = DEFAULT_DEVICE_MAP; + volatile int hold = 0; + int opt; + + progname = "grub-emu"; + + while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1) + switch (opt) + { + case 'r': + root_dev = optarg; + break; + case 'd': + dir = optarg; + break; + case 'm': + dev_map = optarg; + break; + case 'v': + verbosity++; + break; + case 'H': + hold = (optarg ? atoi (optarg) : -1); + break; + case 'h': + return usage (0); + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + default: + return usage (1); + } + + if (optind < argc) + { + fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]); + return usage (1); + } + + /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */ + if (hold && verbosity > 0) + printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n", + progname, (int) getpid ()); + while (hold) + { + if (hold > 0) + hold--; + + sleep (1); + } + + signal (SIGINT, SIG_IGN); + grub_console_init (); + + /* XXX: This is a bit unportable. */ + grub_util_biosdisk_init (dev_map); + +#if HAVE_USB_H + grub_libusb_init (); +#endif + + grub_init_all (); + + /* Make sure that there is a root device. */ + if (! root_dev) + { + char *device_name = grub_guess_root_device (dir); + if (! device_name) + grub_util_error ("cannot find a device for %s.\n", dir); + + root_dev = grub_util_get_grub_dev (device_name); + if (! root_dev) + { + grub_util_info ("guessing the root device failed, because of `%s'", + grub_errmsg); + grub_util_error ("Cannot guess the root device. Specify the option ``--root-device''."); + } + } + + dir = grub_get_prefix (dir); + prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); + sprintf (prefix, "(%s)%s", root_dev, dir); + free (dir); + + /* Start GRUB! */ + if (setjmp (main_env) == 0) + grub_main (); + + grub_fini_all (); + + grub_machine_fini (); + + return 0; +} diff --git a/util/grub-fstest.c b/util/grub-fstest.c new file mode 100644 index 0000000..ca25425 --- /dev/null +++ b/util/grub-fstest.c @@ -0,0 +1,622 @@ +/* grub-fstest.c - debug tool for filesystem driver */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +grub_term_input_t +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_output_t +grub_term_get_current_output (void) +{ + return 0; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +static struct grub_command cmd_loopback; +static struct grub_command cmd_blocklist; +static struct grub_command cmd_ls; + +grub_command_t +grub_register_command (const char *name, + grub_err_t (*func) (struct grub_arg_list * state, + int argc, char **args), + unsigned flags, + const char *summary __attribute__ ((unused)), + const char *description __attribute__ ((unused)), + const struct grub_arg_option *options) +{ + grub_command_t cmd = 0; + + if (!grub_strcmp (name, "loopback")) + cmd = &cmd_loopback; + else if (!grub_strcmp (name, "blocklist")) + cmd = &cmd_blocklist; + else if (!grub_strcmp (name, "ls")) + cmd = &cmd_ls; + + if (cmd) + { + cmd->func = func; + cmd->flags = flags; + cmd->options = options; + } + return NULL; +} + +static grub_err_t +execute_command (grub_command_t cmd, int n, char **args) +{ + int maxargs = 0; + grub_err_t ret = 0; + struct grub_arg_list *state; + struct grub_arg_option *parser; + char **parsed_arglist; + int numargs; + + /* Count the amount of options the command has. */ + parser = (struct grub_arg_option *) cmd->options; + while (parser && (parser++)->doc) + maxargs++; + + /* Set up the option state. */ + state = grub_malloc (sizeof (struct grub_arg_list) * maxargs); + grub_memset (state, 0, sizeof (struct grub_arg_list) * maxargs); + + /* Start the command. */ + if (!(cmd->flags & GRUB_COMMAND_FLAG_NO_ARG_PARSE)) + { + if (grub_arg_parse (cmd, n, args, state, &parsed_arglist, &numargs)) + ret = (cmd->func) (state, numargs, parsed_arglist); + } + else + ret = (cmd->func) (state, n, args); + + grub_free (state); + + return ret; +} + +void +grub_unregister_command (const char *name __attribute__ ((unused))) +{ +} + +#define CMD_LS 1 +#define CMD_CP 2 +#define CMD_CMP 3 +#define CMD_HEX 4 +#define CMD_CRC 6 +#define CMD_BLOCKLIST 7 + +#define BUF_SIZE 32256 + +static grub_off_t skip, leng; + +static void +read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) +{ + static char buf[BUF_SIZE]; + grub_file_t file; + grub_off_t ofs, len; + + if ((pathname[0] == '-') && (pathname[1] == 0)) + { + grub_device_t dev; + + dev = grub_device_open (0); + if ((! dev) || (! dev->disk)) + grub_util_error ("Can\'t open device."); + + grub_util_info ("total sectors : %lld.", + (unsigned long long) dev->disk->total_sectors); + + if (! leng) + leng = (dev->disk->total_sectors << GRUB_DISK_SECTOR_BITS) - skip; + + while (leng) + { + grub_size_t len; + + len = (leng > BUF_SIZE) ? BUF_SIZE : leng; + + if (grub_disk_read (dev->disk, 0, skip, len, buf)) + grub_util_error ("Disk read fails at offset %lld, length %d.", + skip, len); + + if (hook (skip, buf, len)) + break; + + skip += len; + leng -= len; + } + + grub_device_close (dev); + return; + } + + file = grub_file_open (pathname); + if (!file) + { + grub_util_error ("cannot open file %s.", pathname); + return; + } + + grub_util_info ("file size : %lld.", (unsigned long long) file->size); + + if (skip > file->size) + { + grub_util_error ("invalid skip value %d."); + return; + } + + ofs = skip; + len = file->size - skip; + if ((leng) && (leng < len)) + len = leng; + + file->offset = skip; + + while (len) + { + grub_ssize_t sz; + + sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len); + if (sz < 0) + { + grub_util_error ("read error at offset %llu.", ofs); + break; + } + + if ((sz == 0) || (hook (ofs, buf, sz))) + break; + + ofs += sz; + len -= sz; + } + + grub_file_close (file); +} + +static void +cmd_cp (char *src, char *dest) +{ + FILE *ff; + + auto int cp_hook (grub_off_t ofs, char *buf, int len); + int cp_hook (grub_off_t ofs, char *buf, int len) + { + (void) ofs; + + if ((int) fwrite (buf, 1, len, ff) != len) + { + grub_util_error ("write error."); + return 1; + } + + return 0; + } + + ff = fopen (dest, "wb"); + if (ff == NULL) + { + grub_util_error ("open error."); + return; + } + read_file (src, cp_hook); + fclose (ff); +} + +static void +cmd_cmp (char *src, char *dest) +{ + FILE *ff; + static char buf_1[BUF_SIZE]; + + auto int cmp_hook (grub_off_t ofs, char *buf, int len); + int cmp_hook (grub_off_t ofs, char *buf, int len) + { + if ((int) fread (buf_1, 1, len, ff) != len) + { + grub_util_error ("read error at offset %llu.", ofs); + return 1; + } + + if (grub_memcmp (buf, buf_1, len)) + { + int i; + + for (i = 0; i < len; i++, ofs++) + if (buf_1[i] != buf[i]) + { + grub_util_error ("compare fail at offset %llu.", ofs); + return 1; + } + } + return 0; + } + + ff = fopen (dest, "rb"); + if (ff == NULL) + { + grub_util_error ("open error."); + return; + } + + if ((skip) && (fseeko (ff, skip, SEEK_SET))) + grub_util_error ("seek error."); + + read_file (src, cmp_hook); + fclose (ff); +} + +static void +cmd_hex (char *pathname) +{ + auto int hex_hook (grub_off_t ofs, char *buf, int len); + int hex_hook (grub_off_t ofs, char *buf, int len) + { + hexdump (ofs, buf, len); + return 0; + } + + read_file (pathname, hex_hook); +} + +static void +cmd_crc (char *pathname) +{ + grub_uint32_t crc = 0; + + auto int crc_hook (grub_off_t ofs, char *buf, int len); + int crc_hook (grub_off_t ofs, char *buf, int len) + { + (void) ofs; + + crc = grub_getcrc32 (crc, buf, len); + return 0; + } + + read_file (pathname, crc_hook); + printf ("%08x\n", crc); +} + +static void +fstest (char **images, int num_disks, int cmd, int n, char **args) +{ + char host_file[128]; + char loop_name[8]; + char *argv[3] = { "-p", loop_name, host_file}; + int i; + + for (i = 0; i < num_disks; i++) + { + if (grub_strlen (images[i]) + 7 > sizeof (host_file)) + grub_util_error ("Pathname %s too long.", images[i]); + + grub_sprintf (loop_name, "loop%d", i); + grub_sprintf (host_file, "(host)%s", images[i]); + + if (execute_command (&cmd_loopback, 3, argv)) + grub_util_error ("loopback command fails."); + } + + grub_raid_rescan (); + switch (cmd) + { + case CMD_LS: + execute_command (&cmd_ls, n, args); + break; + case CMD_CP: + cmd_cp (args[0], args[1]); + break; + case CMD_CMP: + cmd_cmp (args[0], args[1]); + break; + case CMD_HEX: + cmd_hex (args[0]); + break; + case CMD_CRC: + cmd_crc (args[0]); + break; + case CMD_BLOCKLIST: + execute_command (&cmd_blocklist, n, args); + grub_printf ("\n"); + } + + argv[0] = "-d"; + + for (i = 0; i < num_disks; i++) + { + grub_sprintf (loop_name, "loop%d", i); + execute_command (&cmd_loopback, 2, argv); + } +} + +static struct option options[] = { + {"root", required_argument, 0, 'r'}, + {"skip", required_argument, 0, 's'}, + {"length", required_argument, 0, 'n'}, + {"diskcount", required_argument, 0, 'c'}, + {"debug", required_argument, 0, 'd'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-fstest --help'' for more information.\n"); + else + printf ("\ +Usage: grub-fstest [OPTION]... IMAGE_PATH COMMANDS\n\ +\n\ +Debug tool for filesystem driver.\n\ +\nCommands:\n\ + ls PATH list files in PATH\n\ + cp FILE LOCAL copy FILE to local file LOCAL\n\ + cmp FILE LOCAL compare FILE with local file LOCAL\n\ + hex FILE Hex dump FILE\n\ + crc FILE Get crc32 checksum of FILE\n\ + blocklist FILE display blocklist of FILE\n\ +\nOptions:\n\ + -r, --root=DEVICE_NAME set root device\n\ + -s, --skip=N skip N bytes from output file\n\ + -n, --length=N handle N bytes in output file\n\ + -c, --diskcount=N N input files\n\ + -d, --debug=S Set debug environment variable\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n", PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *debug_str = 0, *root = 0, *default_root, *alloc_root; + int i, cmd, num_opts, image_index, num_disks = 1; + + progname = "grub-fstest"; + + /* Find the first non option entry. */ + for (num_opts = 1; num_opts < argc; num_opts++) + if (argv[num_opts][0] == '-') + { + if ((argv[num_opts][2] == 0) && (num_opts < argc - 1) && + ((argv[num_opts][1] == 'r') || + (argv[num_opts][1] == 's') || + (argv[num_opts][1] == 'n') || + (argv[num_opts][1] == 'c') || + (argv[num_opts][1] == 'd'))) + num_opts++; + } + else + break; + + /* Check for options. */ + while (1) + { + int c = getopt_long (num_opts, argv, "r:s:n:c:d:hVv", options, 0); + char *p; + + if (c == -1) + break; + else + switch (c) + { + case 'r': + root = optarg; + break; + + case 's': + skip = grub_strtoul (optarg, &p, 0); + if (*p == 's') + skip <<= GRUB_DISK_SECTOR_BITS; + break; + + case 'n': + leng = grub_strtoul (optarg, &p, 0); + if (*p == 's') + leng <<= GRUB_DISK_SECTOR_BITS; + break; + + case 'c': + num_disks = grub_strtoul (optarg, NULL, 0); + if (num_disks < 1) + { + fprintf (stderr, "Invalid disk count.\n"); + usage (1); + } + break; + + case 'd': + debug_str = optarg; + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + /* Obtain PATH. */ + if (optind + num_disks - 1 >= argc) + { + fprintf (stderr, "Not enough pathname.\n"); + usage (1); + } + + image_index = optind; + for (i = 0; i < num_disks; i++, optind++) + if (argv[optind][0] != '/') + { + fprintf (stderr, "Must use absolute path.\n"); + usage (1); + } + + cmd = 0; + if (optind < argc) + { + int nparm = 0; + + if (!grub_strcmp (argv[optind], "ls")) + { + cmd = CMD_LS; + } + else if (!grub_strcmp (argv[optind], "cp")) + { + cmd = CMD_CP; + nparm = 2; + } + else if (!grub_strcmp (argv[optind], "cmp")) + { + cmd = CMD_CMP; + nparm = 2; + } + else if (!grub_strcmp (argv[optind], "hex")) + { + cmd = CMD_HEX; + nparm = 1; + } + else if (!grub_strcmp (argv[optind], "crc")) + { + cmd = CMD_CRC; + nparm = 1; + } + else if (!grub_strcmp (argv[optind], "blocklist")) + { + cmd = CMD_BLOCKLIST; + nparm = 1; + } + else + { + fprintf (stderr, "Invalid command %s.\n", argv[optind]); + usage (1); + } + + if (optind + 1 + nparm > argc) + { + fprintf (stderr, "Invalid parameter for command %s.\n", + argv[optind]); + usage (1); + } + + optind++; + } + else + { + fprintf (stderr, "No command is specified.\n"); + usage (1); + } + + /* Initialize all modules. */ + grub_init_all (); + + if (debug_str) + grub_env_set ("debug", debug_str); + + default_root = (num_disks == 1) ? "loop0" : "md0"; + alloc_root = 0; + if (root) + { + if ((*root >= '0') && (*root <= '9')) + { + alloc_root = xmalloc (strlen (default_root) + strlen (root) + 2); + + sprintf (alloc_root, "%s,%s", default_root, root); + root = alloc_root; + } + } + else + root = default_root; + + grub_env_set ("root", root); + + if (alloc_root) + free (alloc_root); + + /* Do it. */ + fstest (argv + image_index, num_disks, cmd, argc - optind, argv + optind); + + /* Free resources. */ + grub_fini_all (); + + return 0; +} diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in new file mode 100644 index 0000000..2d7510f --- /dev/null +++ b/util/grub-mkconfig.in @@ -0,0 +1,217 @@ +#! /bin/sh -e + +# Generate grub.cfg by inspecting /boot contents. +# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +sbindir=@sbindir@ +libdir=@libdir@ +sysconfdir=@sysconfdir@ +grub_prefix=`echo /boot/grub | sed ${transform}` +grub_cfg="" +grub_mkconfig_dir=${sysconfdir}/grub.d + +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` +grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + -o) + shift + grub_cfg=$1 + ;; + --output=) + grub_cfg=`echo "$option" | sed 's/--output=//'` + ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + esac +done + +. ${libdir}/grub/grub-mkconfig_lib + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + root=f + case "`uname 2>/dev/null`" in + CYGWIN*) + # Cygwin: Assume root if member of admin group + for g in `id -G 2>/dev/null` ; do + case $g in + 0|544) root=t ;; + esac + done ;; + esac + if [ $root != t ] ; then + echo "$0: You must run this as root" >&2 + exit 1 + fi +fi + +set $grub_mkdevicemap dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +set $grub_probe dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +mkdir -p ${grub_prefix} + +if test -e ${grub_prefix}/device.map ; then : ; else + grub-mkdevicemap +fi + +# Device containing our userland. Typically used for root= parameter. +GRUB_DEVICE="`${grub_probe} --target=device /`" +GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true + +# Device containing our /boot partition. Usually the same as GRUB_DEVICE. +GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" +GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true + +# Filesystem for the device containing our userland. Used for stuff like +# choosing Hurd filesystem module. +GRUB_FS="`${grub_probe} --target=fs / 2> /dev/null || echo unknown`" + +if test -f ${sysconfdir}/default/grub ; then + . ${sysconfdir}/default/grub +fi + +# XXX: should this be deprecated at some point? +if [ "x${GRUB_TERMINAL}" != "x" ] ; then + GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}" + GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}" +fi + +case x${GRUB_TERMINAL_OUTPUT} in + x) + # If this platform supports gfxterm, try to use it. + if test -e ${grub_prefix}/gfxterm.mod ; then + GRUB_TERMINAL_OUTPUT=gfxterm + fi + ;; + xconsole | xserial | xofconsole | xgfxterm) ;; + *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;; +esac + +# check for terminals that require fonts +case ${GRUB_TERMINAL_OUTPUT} in + gfxterm) + if path=`font_path` ; then + GRUB_FONT_PATH="${path}" + else + # fallback to the native terminal for this platform + unset GRUB_TERMINAL_OUTPUT + fi + ;; +esac + +# does our terminal support utf-8 ? +case ${GRUB_TERMINAL_OUTPUT} in + gfxterm) ;; + *) + # make sure all our children behave in conformance with ascii.. + export LANG=C + ;; +esac + +# These are defined in this script, export them here so that user can +# override them. +export GRUB_DEVICE GRUB_DEVICE_UUID GRUB_DEVICE_BOOT GRUB_DEVICE_BOOT_UUID GRUB_FS GRUB_FONT_PATH GRUB_PRELOAD_MODULES + +# These are optional, user-defined variables. +export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL_OUTPUT GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE + +if test "x${grub_cfg}" != "x"; then + rm -f ${grub_cfg}.new + exec > ${grub_cfg}.new + + # Allow this to fail, since /boot/grub/ might need to be fatfs to support some + # firmware implementations (e.g. OFW or EFI). + chmod 444 ${grub_cfg}.new || true +fi +echo "Generating grub.cfg ..." >&2 + +cat << EOF +# +# DO NOT EDIT THIS FILE +# +# It is automatically generated by $0 using templates +# from ${update_grub_dir} and settings from ${sysconfdir}/default/grub +# +EOF + +for i in ${grub_mkconfig_dir}/* ; do + case "$i" in + # emacsen backup files. FIXME: support other editors + *~) ;; + *) + if grub_file_is_not_garbage "$i" && test -x "$i" ; then + echo + echo "### BEGIN $i ###" + "$i" + echo "### END $i ###" + fi + ;; + esac +done + +if test "x${grub_cfg}" != "x" ; then + # none of the children aborted with error, install the new grub.cfg + mv -f ${grub_cfg}.new ${grub_cfg} +fi + +echo "done" >&2 diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in new file mode 100644 index 0000000..0c5c456 --- /dev/null +++ b/util/grub-mkconfig_lib.in @@ -0,0 +1,178 @@ +# Helper library for grub-mkconfig +# Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +datarootdir=@datarootdir@ +datadir=@datadir@ +sbindir=@sbindir@ +pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` + +grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` + +grub_warn () +{ + echo "Warning: $@" >&2 +} + +make_system_path_relative_to_its_root () +{ + path=$1 + # abort if file doesn't exist + if test -e $path ; then : ;else + return 1 + fi + + # canonicalize + if path=`readlink -f $path` ; then : ; else + return 1 + fi + + # if not a directory, climb up to the directory containing it + if test -d $path ; then + dir=$path + else + dir=`echo $path | sed -e "s,/[^/]*$,,g"` + fi + + num=`stat -c %d $dir` + + # this loop sets $dir to the root directory of the filesystem we're inspecting + while : ; do + parent=`readlink -f $dir/..` + if [ "x`stat -c %d $parent`" = "x$num" ] ; then : ; else + # $parent is another filesystem; we found it. + break + fi + if [ "x$dir" = "x/" ] ; then + # / is our root. + break + fi + dir=$parent + done + + # This function never prints trailing slashes (so that its output can be + # appended a slash unconditionally). Each slash in $dir is considered a + # preceding slash, and therefore the root directory is an empty string. + if [ "$dir" = "/" ] ; then + dir="" + fi + + # XXX: This fails if $dir contains ','. + path=`echo "$path" | sed -e "s,^$dir,,g"` || return 1 + + case "`uname 2>/dev/null`" in + CYGWIN*) + # Cygwin: Check if regular or emulated mount. + if [ -z "$dir" ] || [ "`stat -c %D "$dir/.."`" != 620000 ] ; then + # Reached some mount point not below /cygdrive. + # GRUB does not know Cygwin's emulated mounts, + # convert to Win32 path and remove drive letter. + path=`cygpath -m "$path" | sed -n 's,^[A-Za-z]:,,p'` + test ! -z "$path" || return 1 + fi ;; + esac + + echo "$path" +} + +is_path_readable_by_grub () +{ + path=$1 + + # abort if path doesn't exist + if test -e $path ; then : ;else + return 1 + fi + + # abort if file is in a filesystem we can't read + if ${grub_probe} -t fs $path > /dev/null 2>&1 ; then : ; else + return 1 + fi + + return 0 +} + +convert_system_path_to_grub_path () +{ + path=$1 + + grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead." + + # abort if GRUB can't access the path + if is_path_readable_by_grub ${path} ; then : ; else + return 1 + fi + + if drive=`${grub_probe} -t drive $path` ; then : ; else + return 1 + fi + + if relative_path=`make_system_path_relative_to_its_root $path` ; then : ; else + return 1 + fi + + echo ${drive}${relative_path} +} + +prepare_grub_to_access_device () +{ + device=$1 + + # Abstraction modules aren't auto-loaded. + abstraction="`${grub_probe} --device ${device} --target=abstraction`" + if [ "x${abstraction}" = "x" ] ; then : ; else + echo "insmod ${abstraction}" + fi + + # If there's a filesystem UUID that GRUB is capable of identifying, use it; + # otherwise set root as per value in device.map. + echo "set root=`${grub_probe} --device ${device} --target=drive`" + if fs_uuid="`${grub_probe} --device ${device} --target=fs_uuid 2> /dev/null`" ; then + echo "search --fs-uuid --set ${fs_uuid}" + fi +} + +font_path () +{ + for dir in ${pkgdatadir} /boot/grub /usr/share/grub ; do + # FIXME: We prefer ascii because loading complete fonts is too slow (and + # we don't yet provide the gettext magic that would make unicode useful). + for basename in ascii unicode unifont ; do + path="${dir}/${basename}.pf2" + if is_path_readable_by_grub ${path} > /dev/null ; then + echo "${path}" + return 0 + fi + done + done + + return 1 +} + +grub_file_is_not_garbage () +{ + if test -f "$1" ; then + case "$1" in + *.dpkg-dist|*.dpkg-old|*.dpkg-tmp) return 1 ;; # debian dpkg + esac + else + return 1 + fi + return 0 +} diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c new file mode 100644 index 0000000..fa8b158 --- /dev/null +++ b/util/grub-mkdevicemap.c @@ -0,0 +1,728 @@ +/* grub-mkdevicemap.c - make a device map file automatically */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define _GNU_SOURCE 1 +#include + +#ifdef __linux__ +# if !defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) +/* Maybe libc doesn't have large file support. */ +# include /* _llseek */ +# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ +# include /* ioctl */ +# ifndef HDIO_GETGEO +# define HDIO_GETGEO 0x0301 /* get device geometry */ +/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is + defined. */ +struct hd_geometry +{ + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; +}; +# endif /* ! HDIO_GETGEO */ +# ifndef FLOPPY_MAJOR +# define FLOPPY_MAJOR 2 /* the major number for floppy */ +# endif /* ! FLOPPY_MAJOR */ +# ifndef MAJOR +# define MAJOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) ((__dev >> 8) & 0xfff) \ + | ((unsigned int) (__dev >> 32) & ~0xfff); \ + }) +# endif /* ! MAJOR */ +# ifndef CDROM_GET_CAPABILITY +# define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ +# endif /* ! CDROM_GET_CAPABILITY */ +# ifndef BLKGETSIZE +# define BLKGETSIZE _IO(0x12,96) /* return device size */ +# endif /* ! BLKGETSIZE */ +#endif /* __linux__ */ + +/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with + kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */ +#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__) +# define __FreeBSD_kernel__ +#endif +#ifdef __FreeBSD_kernel__ + /* Obtain version of kFreeBSD headers */ +# include +# ifndef __FreeBSD_kernel_version +# define __FreeBSD_kernel_version __FreeBSD_version +# endif + + /* Runtime detection of kernel */ +# include +int +get_kfreebsd_version (void) +{ + struct utsname uts; + int major; + int minor; + int v[2]; + + uname (&uts); + sscanf (uts.release, "%d.%d", &major, &minor); + + if (major >= 9) + major = 9; + if (major >= 5) + { + v[0] = minor/10; v[1] = minor%10; + } + else + { + v[0] = minor%10; v[1] = minor/10; + } + return major*100000+v[0]*10000+v[1]*1000; +} +#endif /* __FreeBSD_kernel__ */ + +#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) +# include /* ioctl */ +# include +# include /* CDIOCCLRDEBUG */ +# if defined(__FreeBSD_kernel__) +# include +# if __FreeBSD_kernel_version >= 500040 +# include +# endif +# endif /* __FreeBSD_kernel__ */ +#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ + +#ifdef HAVE_OPENDISK +# include +#endif /* HAVE_OPENDISK */ + +#ifdef __linux__ +/* Check if we have devfs support. */ +static int +have_devfs (void) +{ + struct stat st; + return stat ("/dev/.devfsd", &st) == 0; +} +#endif /* __linux__ */ + +/* These three functions are quite different among OSes. */ +static void +get_floppy_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + if (have_devfs ()) + sprintf (name, "/dev/floppy/%d", unit); + else + sprintf (name, "/dev/fd%d", unit); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/fd%d", unit); + else + sprintf (name, "/dev/rfd%d", unit); +#elif defined(__NetBSD__) + /* NetBSD */ + /* opendisk() doesn't work for floppies. */ + sprintf (name, "/dev/rfd%da", unit); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rfd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__CYGWIN__) + /* Cygwin */ + sprintf (name, "/dev/fd%d", unit); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; +#else +# warning "BIOS floppy drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_ide_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/hd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/hd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/ad%d", unit); + else + sprintf (name, "/dev/rwd%d", unit); +#elif defined(__NetBSD__) && defined(HAVE_OPENDISK) + /* NetBSD */ + char shortname[16]; + int fd; + + sprintf (shortname, "wd%d", unit); + fd = opendisk (shortname, O_RDONLY, name, + 16, /* length of NAME */ + 0 /* char device */ + ); + close (fd); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rwd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could + contain SCSI disks. */ + sprintf (name, "/dev/hd%d", unit); +#elif defined(__CYGWIN__) + /* Cygwin emulates all disks as /dev/sdX. */ + (void) unit; + *name = 0; +#elif defined(__MINGW32__) + sprintf (name, "//./PHYSICALDRIVE%d", unit); +#else +# warning "BIOS IDE drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +static void +get_scsi_disk_name (char *name, int unit) +{ +#if defined(__linux__) + /* GNU/Linux */ + sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__GNU__) + /* GNU/Hurd */ + sprintf (name, "/dev/sd%d", unit); +#elif defined(__FreeBSD_kernel__) + /* kFreeBSD */ + if (get_kfreebsd_version () >= 400000) + sprintf (name, "/dev/da%d", unit); + else + sprintf (name, "/dev/rda%d", unit); +#elif defined(__NetBSD__) && defined(HAVE_OPENDISK) + /* NetBSD */ + char shortname[16]; + int fd; + + sprintf (shortname, "sd%d", unit); + fd = opendisk (shortname, O_RDONLY, name, + 16, /* length of NAME */ + 0 /* char device */ + ); + close (fd); +#elif defined(__OpenBSD__) + /* OpenBSD */ + sprintf (name, "/dev/rsd%dc", unit); +#elif defined(__QNXNTO__) + /* QNX RTP */ + /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to + disable the detection of SCSI disks here. */ + *name = 0; +#elif defined(__CYGWIN__) + /* Cygwin emulates all disks as /dev/sdX. */ + sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; +#else +# warning "BIOS SCSI drives cannot be guessed in your operating system." + /* Set NAME to a bogus string. */ + *name = 0; +#endif +} + +#ifdef __linux__ +static void +get_virtio_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/vd%c", unit + 'a'); +} + +static void +get_dac960_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/rd/c%dd%d", controller, drive); +} + +static void +get_ataraid_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/ataraid/d%c", unit + '0'); +} + +static void +get_i2o_disk_name (char *name, char unit) +{ + sprintf (name, "/dev/i2o/hd%c", unit); +} + +static void +get_cciss_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/cciss/c%dd%d", controller, drive); +} + +static void +get_ida_disk_name (char *name, int controller, int drive) +{ + sprintf (name, "/dev/ida/c%dd%d", controller, drive); +} + +static void +get_mmc_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/mmcblk%d", unit); +} + +static void +get_xvd_disk_name (char *name, int unit) +{ + sprintf (name, "/dev/xvd%c", unit + 'a'); +} +#endif + +/* Check if DEVICE can be read. If an error occurs, return zero, + otherwise return non-zero. */ +static int +check_device (const char *device) +{ + char buf[512]; + FILE *fp; + + /* If DEVICE is empty, just return error. */ + if (*device == 0) + return 0; + + fp = fopen (device, "r"); + if (! fp) + { + switch (errno) + { +#ifdef ENOMEDIUM + case ENOMEDIUM: +# if 0 + /* At the moment, this finds only CDROMs, which can't be + read anyway, so leave it out. Code should be + reactivated if `removable disks' and CDROMs are + supported. */ + /* Accept it, it may be inserted. */ + return 1; +# endif + break; +#endif /* ENOMEDIUM */ + default: + /* Break case and leave. */ + break; + } + /* Error opening the device. */ + return 0; + } + + /* Make sure CD-ROMs don't get assigned a BIOS disk number + before SCSI disks! */ +#ifdef __linux__ +# ifdef CDROM_GET_CAPABILITY + if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0) + return 0; +# else /* ! CDROM_GET_CAPABILITY */ + /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */ + { + struct hd_geometry hdg; + struct stat st; + + if (fstat (fileno (fp), &st)) + return 0; + + /* If it is a block device and isn't a floppy, check if HDIO_GETGEO + succeeds. */ + if (S_ISBLK (st.st_mode) + && MAJOR (st.st_rdev) != FLOPPY_MAJOR + && ioctl (fileno (fp), HDIO_GETGEO, &hdg)) + return 0; + } +# endif /* ! CDROM_GET_CAPABILITY */ +#endif /* __linux__ */ + +#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) +# ifdef CDIOCCLRDEBUG + if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0) + return 0; +# endif /* CDIOCCLRDEBUG */ +#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ + + /* Attempt to read the first sector. */ + if (fread (buf, 1, 512, fp) != 512) + { + fclose (fp); + return 0; + } + + fclose (fp); + return 1; +} + +static void +make_device_map (const char *device_map, int floppy_disks) +{ + FILE *fp; + int num_hd = 0; + int i; + + if (strcmp (device_map, "-") == 0) + fp = stdout; + else + fp = fopen (device_map, "w"); + + if (! fp) + grub_util_error ("cannot open %s", device_map); + + /* Floppies. */ + for (i = 0; i < floppy_disks; i++) + { + char name[16]; + struct stat st; + + get_floppy_disk_name (name, i); + if (stat (name, &st) < 0) + break; + /* In floppies, write the map, whether check_device succeeds + or not, because the user just may not insert floppies. */ + if (fp) + fprintf (fp, "(fd%d)\t%s\n", i, name); + } + +#ifdef __linux__ + if (have_devfs ()) + { + while (1) + { + char discn[32]; + char name[PATH_MAX]; + struct stat st; + + /* Linux creates symlinks "/dev/discs/discN" for convenience. + The way to number disks is the same as GRUB's. */ + sprintf (discn, "/dev/discs/disc%d", num_hd); + if (stat (discn, &st) < 0) + break; + + if (realpath (discn, name)) + { + strcat (name, "/disc"); + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + } + + num_hd++; + } + + goto finish; + } +#endif /* __linux__ */ + + /* IDE disks. */ + for (i = 0; i < 20; i++) + { + char name[16]; + + get_ide_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + +#ifdef __linux__ + /* Virtio disks. */ + for (i = 0; i < 20; i++) + { + char name[16]; + + get_virtio_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + + /* ATARAID disks. */ + for (i = 0; i < 8; i++) + { + char name[20]; + + get_ataraid_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + + /* Xen virtual block devices. */ + for (i = 0; i < 16; i++) + { + char name[16]; + + get_xvd_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } +#endif /* __linux__ */ + + /* The rest is SCSI disks. */ + for (i = 0; i < 16; i++) + { + char name[16]; + + get_scsi_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + +#ifdef __linux__ + /* This is for DAC960 - we have + /dev/rd/cdp. + + DAC960 driver currently supports up to 8 controllers, 32 logical + drives, and 7 partitions. */ + { + int controller, drive; + + for (controller = 0; controller < 8; controller++) + { + for (drive = 0; drive < 15; drive++) + { + char name[24]; + + get_dac960_disk_name (name, controller, drive); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + } + } + + /* This is for CCISS - we have + /dev/cciss/cdp. */ + { + int controller, drive; + + for (controller = 0; controller < 3; controller++) + { + for (drive = 0; drive < 10; drive++) + { + char name[24]; + + get_cciss_disk_name (name, controller, drive); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + } + } + + /* This is for Compaq Intelligent Drive Array - we have + /dev/ida/cdp. */ + { + int controller, drive; + + for (controller = 0; controller < 3; controller++) + { + for (drive = 0; drive < 10; drive++) + { + char name[24]; + + get_ida_disk_name (name, controller, drive); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + } + } + + /* This is for I2O - we have /dev/i2o/hd */ + { + char unit; + + for (unit = 'a'; unit < 'f'; unit++) + { + char name[24]; + + get_i2o_disk_name (name, unit); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + } + + /* MultiMediaCard (MMC). */ + for (i = 0; i < 10; i++) + { + char name[16]; + + get_mmc_disk_name (name, i); + if (check_device (name)) + { + fprintf (fp, "(hd%d)\t%s\n", num_hd, name); + num_hd++; + } + } + + finish: +#endif /* __linux__ */ + + if (fp != stdout) + fclose (fp); +} + +static struct option options[] = + { + {"device-map", required_argument, 0, 'm'}, + {"probe-second-floppy", no_argument, 0, 's'}, + {"no-floppy", no_argument, 0, 'n'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, + "Try ``grub-mkdevicemap --help'' for more information.\n"); + else + printf ("\ +Usage: grub-mkdevicemap [OPTION]...\n\ +\n\ +Generate a device map file automatically.\n\ +\n\ + -n, --no-floppy do not probe any floppy drive\n\ + -s, --probe-second-floppy probe the second floppy drive\n\ + -m, --device-map=FILE use FILE as the device map [default=%s]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", + DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *dev_map = 0; + int floppy_disks = 1; + + progname = "grub-mkdevicemap"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "snm:r:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'm': + if (dev_map) + free (dev_map); + + dev_map = xstrdup (optarg); + break; + + case 'n': + floppy_disks = 0; + break; + + case 's': + floppy_disks = 2; + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); + + free (dev_map); + + return 0; +} diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c new file mode 100644 index 0000000..cfd6f9d --- /dev/null +++ b/util/grub-mkfont.c @@ -0,0 +1,620 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include FT_FREETYPE_H +#include + +#define GRUB_FONT_DEFAULT_SIZE 16 + +#define GRUB_FONT_RANGE_BLOCK 1024 + +struct grub_glyph_info +{ + struct grub_glyph_info *next; + grub_uint32_t char_code; + int width; + int height; + int x_ofs; + int y_ofs; + int device_width; + int bitmap_size; + grub_uint8_t bitmap[0]; +}; + +#define GRUB_FONT_FLAG_BOLD 1 +#define GRUB_FONT_FLAG_NOBITMAP 2 +#define GRUB_FONT_FLAG_NOHINTING 4 +#define GRUB_FONT_FLAG_FORCEHINT 8 + +struct grub_font_info +{ + char* name; + int style; + int desc; + int size; + int max_width; + int max_height; + int min_y; + int flags; + int num_range; + grub_uint32_t *ranges; + struct grub_glyph_info *glyph; +}; + +static struct option options[] = +{ + {"output", required_argument, 0, 'o'}, + {"name", required_argument, 0, 'n'}, + {"index", required_argument, 0, 'i'}, + {"range", required_argument, 0, 'r'}, + {"size", required_argument, 0, 's'}, + {"desc", required_argument, 0, 'd'}, + {"bold", no_argument, 0, 'b'}, + {"no-bitmap", no_argument, 0, 0x100}, + {"no-hinting", no_argument, 0, 0x101}, + {"force-autohint", no_argument, 0, 'a'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +int font_verbosity; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-mkfont --help'' for more information.\n"); + else + printf ("\ +Usage: grub-mkfont [OPTIONS] FONT_FILES\n\ +\nOptions:\n\ + -o, --output=FILE_NAME set output file name\n\ + -i, --index=N set face index\n\ + -r, --range=A-B[,C-D] set font range\n\ + -n, --name=S set font family name\n\ + -s, --size=N set font size\n\ + -d, --desc=N set font descent\n\ + -b, --bold convert to bold font\n\ + -a, --force-autohint force autohint\n\ + --no-hinting disable hinting\n\ + --no-bitmap ignore bitmap strikes when loading\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n", PACKAGE_BUGREPORT); + + exit (status); +} + +void +add_pixel (grub_uint8_t **data, int *mask, int not_blank) +{ + if (*mask == 0) + { + (*data)++; + **data = 0; + *mask = 128; + } + + if (not_blank) + **data |= *mask; + + *mask >>= 1; +} + +void +add_char (struct grub_font_info *font_info, FT_Face face, + grub_uint32_t char_code) +{ + struct grub_glyph_info *glyph_info, **p_glyph; + int width, height; + grub_uint8_t *data; + int mask, i, j, bitmap_size; + FT_GlyphSlot glyph; + int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; + + if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP) + flag |= FT_LOAD_NO_BITMAP; + + if (font_info->flags & GRUB_FONT_FLAG_NOHINTING) + flag |= FT_LOAD_NO_HINTING; + else if (font_info->flags & GRUB_FONT_FLAG_FORCEHINT) + flag |= FT_LOAD_FORCE_AUTOHINT; + + if (FT_Load_Char (face, char_code, flag)) + return; + + glyph = face->glyph; + + if (font_info->flags & GRUB_FONT_FLAG_BOLD) + FT_GlyphSlot_Embolden (glyph); + + p_glyph = &font_info->glyph; + while ((*p_glyph) && ((*p_glyph)->char_code > char_code)) + { + p_glyph = &(*p_glyph)->next; + } + + /* Ignore duplicated glyph. */ + if ((*p_glyph) && ((*p_glyph)->char_code == char_code)) + return; + + width = glyph->bitmap.width; + height = glyph->bitmap.rows; + + bitmap_size = ((width * height + 7) / 8); + glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size); + glyph_info->bitmap_size = bitmap_size; + + glyph_info->next = *p_glyph; + *p_glyph = glyph_info; + + glyph_info->char_code = char_code; + glyph_info->width = width; + glyph_info->height = height; + glyph_info->x_ofs = glyph->bitmap_left; + glyph_info->y_ofs = glyph->bitmap_top - height; + glyph_info->device_width = glyph->metrics.horiAdvance / 64; + + if (width > font_info->max_width) + font_info->max_width = width; + + if (height > font_info->max_height) + font_info->max_height = height; + + if (glyph_info->y_ofs < font_info->min_y) + font_info->min_y = glyph_info->y_ofs; + + mask = 0; + data = &glyph_info->bitmap[0] - 1; + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) + add_pixel (&data, &mask, + glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & + (1 << (7 - (i & 7)))); +} + +void +add_font (struct grub_font_info *font_info, FT_Face face) +{ + if (font_info->num_range) + { + int i; + grub_uint32_t j; + + for (i = 0; i < font_info->num_range; i++) + for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1]; + j++) + add_char (font_info, face, j); + } + else + { + grub_uint32_t char_code, glyph_index; + + for (char_code = FT_Get_First_Char (face, &glyph_index); + glyph_index; + char_code = FT_Get_Next_Char (face, char_code, &glyph_index)) + add_char (font_info, face, char_code); + } +} + +void +write_string_section (char *name, char *str, int* offset, FILE* file) +{ + grub_uint32_t leng, leng_be32; + + leng = strlen (str) + 1; + leng_be32 = grub_cpu_to_be32 (leng); + + grub_util_write_image (name, 4, file); + grub_util_write_image ((char *) &leng_be32, 4, file); + grub_util_write_image (str, leng, file); + + *offset += 8 + leng; +} + +void +write_be16_section (char *name, grub_uint16_t data, int* offset, FILE* file) +{ + grub_uint32_t leng; + + leng = grub_cpu_to_be32 (2); + data = grub_cpu_to_be16 (data); + grub_util_write_image (name, 4, file); + grub_util_write_image ((char *) &leng, 4, file); + grub_util_write_image ((char *) &data, 2, file); + + *offset += 10; +} + +void +print_glyphs (struct grub_font_info *font_info) +{ + int num; + struct grub_glyph_info *glyph; + char line[512]; + + for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++) + { + int x, y, xmax, xmin, ymax, ymin; + grub_uint8_t *bitmap, mask; + + printf ("\nGlyph #%d, U+%04x\n", num, glyph->char_code); + printf ("Width %d, Height %d, X offset %d, Y offset %d, Device width %d\n", + glyph->width, glyph->height, glyph->x_ofs, glyph->y_ofs, + glyph->device_width); + + xmax = glyph->x_ofs + glyph->width; + if (xmax < glyph->device_width) + xmax = glyph->device_width; + + xmin = glyph->x_ofs; + if (xmin > 0) + xmin = 0; + + ymax = glyph->y_ofs + glyph->height; + if (ymax < font_info->size - font_info->desc) + ymax = font_info->size - font_info->desc; + + ymin = glyph->y_ofs; + if (ymin > - font_info->desc) + ymin = - font_info->desc; + + bitmap = glyph->bitmap; + mask = 0x80; + for (y = ymax - 1; y >= ymin; y--) + { + int line_pos; + + line_pos = 0; + for (x = xmin; x < xmax; x++) + { + if ((x >= glyph->x_ofs) && + (x < glyph->x_ofs + glyph->width) && + (y >= glyph->y_ofs) && + (y < glyph->y_ofs + glyph->height)) + { + line[line_pos++] = (*bitmap & mask) ? '#' : '_'; + mask >>= 1; + if (mask == 0) + { + mask = 0x80; + bitmap++; + } + } + else if ((x >= 0) && + (x < glyph->device_width) && + (y >= - font_info->desc) && + (y < font_info->size - font_info->desc)) + { + line[line_pos++] = ((x == 0) || (y == 0)) ? '+' : '.'; + } + else + line[line_pos++] = '*'; + } + line[line_pos] = 0; + printf ("%s\n", line); + } + } +} + +void +write_font (struct grub_font_info *font_info, char *output_file) +{ + FILE *file; + grub_uint32_t leng, data; + char style_name[20], *font_name; + struct grub_glyph_info *cur, *pre; + int num, offset; + + file = fopen (output_file, "wb"); + if (! file) + grub_util_error ("Can\'t write to file %s.", output_file); + + offset = 0; + + leng = grub_cpu_to_be32 (4); + grub_util_write_image ("FILE", 4, file); + grub_util_write_image ((char *) &leng, 4, file); + grub_util_write_image ("PFF2", 4, file); + offset += 12; + + if (! font_info->name) + font_info->name = "Unknown"; + + if (font_info->flags & GRUB_FONT_FLAG_BOLD) + font_info->style |= FT_STYLE_FLAG_BOLD; + + style_name[0] = 0; + if (font_info->style & FT_STYLE_FLAG_BOLD) + strcpy (style_name, " Bold"); + + if (font_info->style & FT_STYLE_FLAG_ITALIC) + strcat (style_name, " Italic"); + + if (! style_name[0]) + strcpy (style_name, " Regular"); + + asprintf (&font_name, "%s %s %d", font_info->name, &style_name[1], + font_info->size); + + write_string_section ("NAME", font_name, &offset, file); + write_string_section ("FAMI", font_info->name, &offset, file); + write_string_section ("WEIG", + (font_info->style & FT_STYLE_FLAG_BOLD) ? + "bold" : "normal", + &offset, file); + write_string_section ("SLAN", + (font_info->style & FT_STYLE_FLAG_ITALIC) ? + "italic" : "normal", + &offset, file); + + write_be16_section ("PTSZ", font_info->size, &offset, file); + write_be16_section ("MAXW", font_info->max_width, &offset, file); + write_be16_section ("MAXH", font_info->max_height, &offset, file); + + if (! font_info->desc) + { + if (font_info->min_y >= 0) + font_info->desc = 1; + else + font_info->desc = - font_info->min_y; + } + + write_be16_section ("ASCE", font_info->size - font_info->desc, &offset, file); + write_be16_section ("DESC", font_info->desc, &offset, file); + + if (font_verbosity > 0) + { + printf ("Font name: %s\n", font_name); + printf ("Max width: %d\n", font_info->max_width); + printf ("Max height: %d\n", font_info->max_height); + printf ("Font ascent: %d\n", font_info->size - font_info->desc); + printf ("Font descent: %d\n", font_info->desc); + } + + num = 0; + pre = 0; + cur = font_info->glyph; + while (cur) + { + struct grub_glyph_info *nxt; + + nxt = cur->next; + cur->next = pre; + pre = cur; + cur = nxt; + num++; + } + + font_info->glyph = pre; + + if (font_verbosity > 0) + printf ("Number of glyph: %d\n", num); + + leng = grub_cpu_to_be32 (num * 9); + grub_util_write_image ("CHIX", 4, file); + grub_util_write_image ((char *) &leng, 4, file); + offset += 8 + num * 9 + 8; + + for (cur = font_info->glyph; cur; cur = cur->next) + { + data = grub_cpu_to_be32 (cur->char_code); + grub_util_write_image ((char *) &data, 4, file); + data = 0; + grub_util_write_image ((char *) &data, 1, file); + data = grub_cpu_to_be32 (offset); + grub_util_write_image ((char *) &data, 4, file); + offset += 10 + cur->bitmap_size; + } + + leng = 0xffffffff; + grub_util_write_image ("DATA", 4, file); + grub_util_write_image ((char *) &leng, 4, file); + + for (cur = font_info->glyph; cur; cur = cur->next) + { + data = grub_cpu_to_be16 (cur->width); + grub_util_write_image ((char *) &data, 2, file); + data = grub_cpu_to_be16 (cur->height); + grub_util_write_image ((char *) &data, 2, file); + data = grub_cpu_to_be16 (cur->x_ofs); + grub_util_write_image ((char *) &data, 2, file); + data = grub_cpu_to_be16 (cur->y_ofs); + grub_util_write_image ((char *) &data, 2, file); + data = grub_cpu_to_be16 (cur->device_width); + grub_util_write_image ((char *) &data, 2, file); + grub_util_write_image ((char *) &cur->bitmap[0], cur->bitmap_size, file); + } + + if (font_verbosity > 1) + print_glyphs (font_info); + + fclose (file); +} + +int +main (int argc, char *argv[]) +{ + struct grub_font_info font_info; + FT_Library ft_lib; + int font_index = 0; + int font_size = 0; + char *output_file = NULL; + + memset (&font_info, 0, sizeof (font_info)); + + progname = "grub-mkfont"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "bao:n:i:s:d:r:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'b': + font_info.flags |= GRUB_FONT_FLAG_BOLD; + break; + + case 0x100: + font_info.flags |= GRUB_FONT_FLAG_NOBITMAP; + break; + + case 0x101: + font_info.flags |= GRUB_FONT_FLAG_NOHINTING; + break; + + case 'a': + font_info.flags |= GRUB_FONT_FLAG_FORCEHINT; + break; + + case 'o': + output_file = optarg; + break; + + case 'n': + font_info.name = optarg; + break; + + case 'i': + font_index = strtoul (optarg, NULL, 0); + break; + + case 's': + font_size = strtoul (optarg, NULL, 0); + break; + + case 'r': + { + char *p = optarg; + + while (1) + { + grub_uint32_t a, b; + + a = strtoul (p, &p, 0); + if (*p != '-') + grub_util_error ("Invalid font range"); + b = strtoul (p + 1, &p, 0); + if ((font_info.num_range & (GRUB_FONT_RANGE_BLOCK - 1)) == 0) + font_info.ranges = xrealloc (font_info.ranges, + (font_info.num_range + + GRUB_FONT_RANGE_BLOCK) * + sizeof (int) * 2); + + font_info.ranges[font_info.num_range * 2] = a; + font_info.ranges[font_info.num_range * 2 + 1] = b; + font_info.num_range++; + + if (*p) + { + if (*p != ',') + grub_util_error ("Invalid font range"); + else + p++; + } + else + break; + } + break; + } + + case 'd': + font_info.desc = strtoul (optarg, NULL, 0); + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + font_verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (! output_file) + grub_util_error ("No output file is specified."); + + if (FT_Init_FreeType (&ft_lib)) + grub_util_error ("FT_Init_FreeType fails"); + + for (; optind < argc; optind++) + { + FT_Face ft_face; + int size; + + if (FT_New_Face (ft_lib, argv[optind], font_index, &ft_face)) + { + grub_util_info ("Can't open file %s, index %d\n", argv[optind], + font_index); + continue; + } + + if ((! font_info.name) && (ft_face->family_name)) + font_info.name = xstrdup (ft_face->family_name); + + size = font_size; + if (! size) + { + if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) || + (! ft_face->num_fixed_sizes)) + size = GRUB_FONT_DEFAULT_SIZE; + else + size = ft_face->available_sizes[0].height; + } + + font_info.style = ft_face->style_flags; + font_info.size = size; + + FT_Set_Pixel_Sizes (ft_face, size, size); + add_font (&font_info, ft_face); + FT_Done_Face (ft_face); + } + + FT_Done_FreeType (ft_lib); + + write_font (&font_info, output_file); + + return 0; +} diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c new file mode 100644 index 0000000..d703d33 --- /dev/null +++ b/util/grub-pe2elf.c @@ -0,0 +1,514 @@ +/* grub-pe2elf.c - tool to convert pe image to elf. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct option options[] = { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} +}; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n"); + else + printf ("\ +Usage: grub-editenv [OPTIONS] input [output]\n\ +\n\ +Tool to convert pe image to elf.\n\ +\nOptions:\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n", PACKAGE_BUGREPORT); + + exit (status); +} + +/* + * Section layout + * + * null + * .text + * .rdata + * .data + * .bss + * .modname + * .moddeps + * .symtab + * .strtab + * relocation sections + */ + +#define TEXT_SECTION 1 +#define RDATA_SECTION 2 +#define DATA_SECTION 3 +#define BSS_SECTION 4 +#define MODNAME_SECTION 5 +#define MODDEPS_SECTION 6 +#define SYMTAB_SECTION 7 +#define STRTAB_SECTION 8 + +#define REL_SECTION 9 +#define MAX_SECTIONS 12 + +#define STRTAB_BLOCK 256 + +static char *strtab; +static int strtab_max, strtab_len; + +Elf32_Ehdr ehdr; +Elf32_Shdr shdr[MAX_SECTIONS]; +int num_sections; +grub_uint32_t offset; + +static int +insert_string (char *name) +{ + int len, result; + + if (*name == '_') + name++; + + len = strlen (name); + if (strtab_len + len >= strtab_max) + { + strtab_max += STRTAB_BLOCK; + strtab = xrealloc (strtab, strtab_max); + } + + strcpy (strtab + strtab_len, name); + result = strtab_len; + strtab_len += len + 1; + + return result; +} + +static int * +write_section_data (FILE* fp, char *image, + struct grub_pe32_coff_header *pe_chdr, + struct grub_pe32_section_table *pe_shdr) +{ + int *section_map; + int i; + + section_map = xmalloc ((pe_chdr->num_sections + 1) * sizeof (int)); + section_map[0] = 0; + + for (i = 0; i < pe_chdr->num_sections; i++, pe_shdr++) + { + grub_uint32_t idx; + + if (! strcmp (pe_shdr->name, ".text")) + { + idx = TEXT_SECTION; + shdr[idx].sh_flags = SHF_ALLOC | SHF_EXECINSTR; + } + else if (! strcmp (pe_shdr->name, ".rdata")) + { + idx = RDATA_SECTION; + shdr[idx].sh_flags = SHF_ALLOC; + } + else if (! strcmp (pe_shdr->name, ".data")) + { + idx = DATA_SECTION; + shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE; + } + else if (! strcmp (pe_shdr->name, ".bss")) + { + idx = BSS_SECTION; + shdr[idx].sh_flags = SHF_ALLOC | SHF_WRITE; + } + else if (! strcmp (pe_shdr->name, ".modname")) + idx = MODNAME_SECTION; + else if (! strcmp (pe_shdr->name, ".moddeps")) + idx = MODDEPS_SECTION; + else + { + section_map[i + 1] = -1; + continue; + } + + section_map[i + 1] = idx; + + shdr[idx].sh_type = (idx == BSS_SECTION) ? SHT_NOBITS : SHT_PROGBITS; + shdr[idx].sh_size = pe_shdr->raw_data_size; + shdr[idx].sh_addralign = 1 << (((pe_shdr->characteristics >> + GRUB_PE32_SCN_ALIGN_SHIFT) & + GRUB_PE32_SCN_ALIGN_MASK) - 1); + + if (idx != BSS_SECTION) + { + shdr[idx].sh_offset = offset; + grub_util_write_image_at (image + pe_shdr->raw_data_offset, + pe_shdr->raw_data_size, offset, fp); + + offset += pe_shdr->raw_data_size; + } + + if (pe_shdr->relocations_offset) + { + char name[5 + strlen (pe_shdr->name)]; + + if (num_sections >= MAX_SECTIONS) + grub_util_error ("Too many sections"); + + sprintf (name, ".rel%s", pe_shdr->name); + + shdr[num_sections].sh_name = insert_string (name); + shdr[num_sections].sh_link = i; + shdr[num_sections].sh_info = idx; + + shdr[idx].sh_name = shdr[num_sections].sh_name + 4; + + num_sections++; + } + else + shdr[idx].sh_name = insert_string (pe_shdr->name); + } + + return section_map; +} + +static void +write_reloc_section (FILE* fp, char *image, + struct grub_pe32_coff_header *pe_chdr, + struct grub_pe32_section_table *pe_shdr, + Elf32_Sym *symtab, + int *symtab_map) +{ + int i; + + for (i = REL_SECTION; i < num_sections; i++) + { + struct grub_pe32_section_table *pe_sec; + struct grub_pe32_reloc *pe_rel; + Elf32_Rel *rel; + int num_rels, j, modified; + + pe_sec = pe_shdr + shdr[i].sh_link; + pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset); + rel = (Elf32_Rel *) xmalloc (pe_sec->num_relocations * sizeof (Elf32_Rel)); + num_rels = 0; + modified = 0; + + for (j = 0; j < pe_sec->num_relocations; j++, pe_rel++) + { + int type; + grub_uint32_t ofs, *addr; + + if ((pe_rel->symtab_index >= pe_chdr->num_symbols) || + (symtab_map[pe_rel->symtab_index] == -1)) + grub_util_error ("Invalid symbol"); + + if (pe_rel->type == GRUB_PE32_REL_I386_DIR32) + type = R_386_32; + else if (pe_rel->type == GRUB_PE32_REL_I386_REL32) + type = R_386_PC32; + else + grub_util_error ("Unknown pe relocation type %d\n", pe_rel->type); + + ofs = pe_rel->offset - pe_sec->virtual_address; + addr = (grub_uint32_t *)(image + pe_sec->raw_data_offset + ofs); + if (type == R_386_PC32) + { + unsigned char code; + + code = image[pe_sec->raw_data_offset + ofs - 1]; + + if (((code != 0xe8) && (code != 0xe9)) || (*addr)) + grub_util_error ("Invalid relocation (%x %x)", code, *addr); + + modified = 1; + if (symtab[symtab_map[pe_rel->symtab_index]].st_shndx) + { + if (symtab[symtab_map[pe_rel->symtab_index]].st_shndx + != shdr[i].sh_info) + grub_util_error ("Cross section call is not allowed"); + + *addr = (symtab[symtab_map[pe_rel->symtab_index]].st_value + - ofs - 4); + + continue; + } + else + *addr = -4; + } + + rel[num_rels].r_offset = ofs; + rel[num_rels].r_info = ELF32_R_INFO (symtab_map[pe_rel->symtab_index], + type); + num_rels++; + } + + if (modified) + grub_util_write_image_at (image + pe_sec->raw_data_offset, + shdr[shdr[i].sh_info].sh_size, + shdr[shdr[i].sh_info].sh_offset, + fp); + + shdr[i].sh_type = SHT_REL; + shdr[i].sh_offset = offset; + shdr[i].sh_link = SYMTAB_SECTION; + shdr[i].sh_addralign = 4; + shdr[i].sh_entsize = sizeof (Elf32_Rel); + shdr[i].sh_size = num_rels * sizeof (Elf32_Rel); + + grub_util_write_image_at (rel, shdr[i].sh_size, offset, fp); + offset += shdr[i].sh_size; + free (rel); + } +} + +static void +write_symbol_table (FILE* fp, char *image, + struct grub_pe32_coff_header *pe_chdr, + struct grub_pe32_section_table *pe_shdr, + int *section_map) +{ + struct grub_pe32_symbol *pe_symtab; + char *pe_strtab; + Elf32_Sym *symtab; + int *symtab_map, num_syms; + int i; + + pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset); + pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols); + + symtab = (Elf32_Sym *) xmalloc ((pe_chdr->num_symbols + 1) * + sizeof (Elf32_Sym)); + memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf32_Sym)); + num_syms = 1; + + symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int)); + + for (i = 0; i < (int) pe_chdr->num_symbols; + i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1) + { + int bind, type; + + symtab_map[i] = -1; + if ((pe_symtab->section > pe_chdr->num_sections) || + (section_map[pe_symtab->section] == -1)) + continue; + + if (! pe_symtab->section) + type = STT_NOTYPE; + else if (pe_symtab->type == GRUB_PE32_DT_FUNCTION) + type = STT_FUNC; + else + type = STT_OBJECT; + + if (pe_symtab->storage_class == GRUB_PE32_SYM_CLASS_EXTERNAL) + bind = STB_GLOBAL; + else + bind = STB_LOCAL; + + if ((type != STT_FUNC) && (pe_symtab->num_aux)) + { + if (! pe_symtab->value) + type = STT_SECTION; + + symtab[num_syms].st_name = shdr[section_map[pe_symtab->section]].sh_name; + } + else + { + char *name; + + name = ((pe_symtab->long_name[0]) ? pe_symtab->short_name : + pe_strtab + pe_symtab->long_name[1]); + + if ((strcmp (name, "_grub_mod_init")) && + (strcmp (name, "_grub_mod_fini")) && + (bind == STB_LOCAL)) + continue; + + symtab[num_syms].st_name = insert_string (name); + } + + symtab[num_syms].st_shndx = section_map[pe_symtab->section]; + symtab[num_syms].st_value = pe_symtab->value; + symtab[num_syms].st_info = ELF32_ST_INFO (bind, type); + + symtab_map[i] = num_syms; + num_syms++; + } + + write_reloc_section (fp, image, pe_chdr, pe_shdr, symtab, symtab_map); + + shdr[SYMTAB_SECTION].sh_name = insert_string (".symtab"); + shdr[SYMTAB_SECTION].sh_type = SHT_SYMTAB; + shdr[SYMTAB_SECTION].sh_offset = offset; + shdr[SYMTAB_SECTION].sh_size = num_syms * sizeof (Elf32_Sym); + shdr[SYMTAB_SECTION].sh_entsize = sizeof (Elf32_Sym); + shdr[SYMTAB_SECTION].sh_link = STRTAB_SECTION; + shdr[SYMTAB_SECTION].sh_addralign = 4; + + grub_util_write_image_at (symtab, shdr[SYMTAB_SECTION].sh_size, + offset, fp); + offset += shdr[SYMTAB_SECTION].sh_size; + + free (symtab); + free (symtab_map); +} + +static void +write_string_table (FILE* fp) +{ + shdr[STRTAB_SECTION].sh_name = insert_string (".strtab"); + shdr[STRTAB_SECTION].sh_type = SHT_STRTAB; + shdr[STRTAB_SECTION].sh_offset = offset; + shdr[STRTAB_SECTION].sh_size = strtab_len; + shdr[STRTAB_SECTION].sh_addralign = 1; + grub_util_write_image_at (strtab, strtab_len, offset, fp); + offset += strtab_len; + + free (strtab); +} + +static void +write_section_header (FILE* fp) +{ + ehdr.e_ident[EI_MAG0] = ELFMAG0; + ehdr.e_ident[EI_MAG1] = ELFMAG1; + ehdr.e_ident[EI_MAG2] = ELFMAG2; + ehdr.e_ident[EI_MAG3] = ELFMAG3; + ehdr.e_ident[EI_VERSION] = EV_CURRENT; + ehdr.e_version = EV_CURRENT; + ehdr.e_type = ET_REL; + + ehdr.e_ident[EI_CLASS] = ELFCLASS32; + ehdr.e_ident[EI_DATA] = ELFDATA2LSB; + ehdr.e_machine = EM_386; + + ehdr.e_ehsize = sizeof (ehdr); + ehdr.e_shentsize = sizeof (Elf32_Shdr); + ehdr.e_shstrndx = STRTAB_SECTION; + + ehdr.e_shoff = offset; + ehdr.e_shnum = num_sections; + grub_util_write_image_at (&shdr, sizeof (Elf32_Shdr) * num_sections, + offset, fp); + + grub_util_write_image_at (&ehdr, sizeof (Elf32_Ehdr), 0, fp); +} + +static void +convert_pe (FILE* fp, char *image) +{ + struct grub_pe32_coff_header *pe_chdr; + struct grub_pe32_section_table *pe_shdr; + int *section_map; + + pe_chdr = (struct grub_pe32_coff_header *) image; + if (grub_le_to_cpu16 (pe_chdr->machine) != GRUB_PE32_MACHINE_I386) + grub_util_error ("Invalid coff image"); + + strtab = xmalloc (STRTAB_BLOCK); + strtab_max = STRTAB_BLOCK; + strtab[0] = 0; + strtab_len = 1; + + offset = sizeof (ehdr); + pe_shdr = (struct grub_pe32_section_table *) (pe_chdr + 1); + num_sections = REL_SECTION; + + section_map = write_section_data (fp, image, pe_chdr, pe_shdr); + + write_symbol_table (fp, image, pe_chdr, pe_shdr, section_map); + free (section_map); + + write_string_table (fp); + + write_section_header (fp); +} + +int +main (int argc, char *argv[]) +{ + char *image; + FILE* fp; + + progname = "grub-pe2elf"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + /* Obtain PATH. */ + if (optind >= argc) + { + fprintf (stderr, "Filename not specified.\n"); + usage (1); + } + + image = grub_util_read_image (argv[optind]); + + if (optind + 1 < argc) + optind++; + + fp = fopen (argv[optind], "wb"); + if (! fp) + grub_util_error ("cannot open %s", argv[optind]); + + convert_pe (fp, image); + + fclose (fp); + + return 0; +} diff --git a/util/grub-probe.c b/util/grub-probe.c new file mode 100644 index 0000000..402b758 --- /dev/null +++ b/util/grub-probe.c @@ -0,0 +1,387 @@ +/* grub-probe.c - probe device information for a given path */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +enum { + PRINT_FS, + PRINT_FS_UUID, + PRINT_DRIVE, + PRINT_DEVICE, + PRINT_PARTMAP, + PRINT_ABSTRACTION, +}; + +int print = PRINT_FS; +static unsigned int argument_is_device = 0; + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +grub_term_input_t +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_output_t +grub_term_get_current_output (void) +{ + return 0; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +static void +probe_partmap (grub_disk_t disk) +{ + char *name; + char *underscore; + + if (disk->partition == NULL) + { + grub_util_info ("No partition map found for %s", disk->name); + return; + } + + name = strdup (disk->partition->partmap->name); + if (! name) + grub_util_error ("Not enough memory"); + + underscore = strchr (name, '_'); + if (! underscore) + grub_util_error ("Invalid partition map %s", name); + + *underscore = '\0'; + printf ("%s\n", name); + free (name); +} + +static void +probe (const char *path, char *device_name) +{ + char *drive_name = NULL; + char *grub_path = NULL; + char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL; + int abstraction_type; + grub_device_t dev = NULL; + grub_fs_t fs; + + if (path == NULL) + { + if (! grub_util_check_block_device (device_name)) + grub_util_error ("%s is not a block device.\n", device_name); + } + else + device_name = grub_guess_root_device (path); + + if (! device_name) + grub_util_error ("cannot find a device for %s.\n", path); + + if (print == PRINT_DEVICE) + { + printf ("%s\n", device_name); + goto end; + } + + abstraction_type = grub_util_get_dev_abstraction (device_name); + /* No need to check for errors; lack of abstraction is permissible. */ + + if (print == PRINT_ABSTRACTION) + { + char *abstraction_name; + switch (abstraction_type) + { + case GRUB_DEV_ABSTRACTION_LVM: + abstraction_name = "lvm"; + break; + case GRUB_DEV_ABSTRACTION_RAID: + abstraction_name = "raid mdraid"; + break; + default: + grub_util_info ("did not find LVM/RAID in %s, assuming raw device", device_name); + goto end; + } + printf ("%s\n", abstraction_name); + goto end; + } + + drive_name = grub_util_get_grub_dev (device_name); + if (! drive_name) + grub_util_error ("Cannot find a GRUB drive for %s. Check your device.map.\n", device_name); + + if (print == PRINT_DRIVE) + { + printf ("(%s)\n", drive_name); + goto end; + } + + grub_util_info ("opening %s", drive_name); + dev = grub_device_open (drive_name); + if (! dev) + grub_util_error ("%s", grub_errmsg); + + if (print == PRINT_PARTMAP) + { + grub_disk_memberlist_t list = NULL, tmp; + + /* Check if dev->disk itself is contained in a partmap. */ + probe_partmap (dev->disk); + + /* In case of LVM/RAID, check the member devices as well. */ + if (dev->disk->dev->memberlist) + list = dev->disk->dev->memberlist (dev->disk); + while (list) + { + probe_partmap (list->disk); + tmp = list->next; + free (list); + list = tmp; + } + goto end; + } + + fs = grub_fs_probe (dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + if (print == PRINT_FS) + { + struct stat st; + + stat (path, &st); + + if (st.st_mode == S_IFREG) + { + /* Regular file. Verify that we can read it properly. */ + + grub_file_t file; + grub_util_info ("reading %s via OS facilities", path); + filebuf_via_sys = grub_util_read_image (path); + + grub_util_info ("reading %s via GRUB facilities", path); + asprintf (&grub_path, "(%s)%s", drive_name, path); + file = grub_file_open (grub_path); + filebuf_via_grub = xmalloc (file->size); + grub_file_read (file, filebuf_via_grub, file->size); + + grub_util_info ("comparing"); + + if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size)) + grub_util_error ("files differ"); + } + printf ("%s\n", fs->name); + } + + if (print == PRINT_FS_UUID) + { + char *uuid; + if (! fs->uuid) + grub_util_error ("%s does not support UUIDs", fs->name); + + fs->uuid (dev, &uuid); + + printf ("%s\n", uuid); + } + + end: + if (dev) + grub_device_close (dev); + free (grub_path); + free (filebuf_via_grub); + free (filebuf_via_sys); + free (drive_name); +} + +static struct option options[] = + { + {"device", no_argument, 0, 'd'}, + {"device-map", required_argument, 0, 'm'}, + {"target", required_argument, 0, 't'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, + "Try ``grub-probe --help'' for more information.\n"); + else + printf ("\ +Usage: grub-probe [OPTION]... [PATH|DEVICE]\n\ +\n\ +Probe device information for a given path (or device, if the -d option is given).\n\ +\n\ + -d, --device given argument is a system device, not a path\n\ + -m, --device-map=FILE use FILE as the device map [default=%s]\n\ + -t, --target=(fs|fs_uuid|drive|device|partmap|abstraction)\n\ + print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", + DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *dev_map = 0; + char *argument; + + progname = "grub-probe"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "dm:t:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'd': + argument_is_device = 1; + break; + + case 'm': + if (dev_map) + free (dev_map); + + dev_map = xstrdup (optarg); + break; + + case 't': + if (!strcmp (optarg, "fs")) + print = PRINT_FS; + else if (!strcmp (optarg, "fs_uuid")) + print = PRINT_FS_UUID; + else if (!strcmp (optarg, "drive")) + print = PRINT_DRIVE; + else if (!strcmp (optarg, "device")) + print = PRINT_DEVICE; + else if (!strcmp (optarg, "partmap")) + print = PRINT_PARTMAP; + else if (!strcmp (optarg, "abstraction")) + print = PRINT_ABSTRACTION; + else + usage (1); + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + /* Obtain ARGUMENT. */ + if (optind >= argc) + { + fprintf (stderr, "No path or device is specified.\n"); + usage (1); + } + + if (optind + 1 != argc) + { + fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + usage (1); + } + + argument = argv[optind]; + + /* Initialize the emulated biosdisk driver. */ + grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP); + + /* Initialize all modules. */ + grub_init_all (); + + /* Do it. */ + if (argument_is_device) + probe (NULL, argument); + else + probe (argument, NULL); + + /* Free resources. */ + grub_fini_all (); + grub_util_biosdisk_fini (); + + free (dev_map); + + return 0; +} diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in new file mode 100644 index 0000000..d8fa416 --- /dev/null +++ b/util/grub.d/00_header.in @@ -0,0 +1,114 @@ +#! /bin/sh -e + +# update-grub helper script. +# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +grub_prefix=`echo /boot/grub | sed ${transform}` + +. ${libdir}/grub/grub-mkconfig_lib + +# Do this as early as possible, since other commands might depend on it. +# (e.g. the `loadfont' command might need lvm or raid modules) +for i in ${GRUB_PRELOAD_MODULES} ; do + echo "insmod $i" +done + +if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi +if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi +if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi + +cat << EOF +set default=${GRUB_DEFAULT} +set timeout=${GRUB_TIMEOUT} +EOF + +case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in + serial:* | *:serial) + if ! test -e ${grub_prefix}/serial.mod ; then + echo "Serial terminal not available on this platform." >&2 ; exit 1 + fi + + if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then + grub_warn "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." + GRUB_SERIAL_COMMAND=serial + fi + echo "${GRUB_SERIAL_COMMAND}" + ;; +esac + +case x${GRUB_TERMINAL_INPUT} in + x) + # Just use the native terminal + ;; + x*) + cat << EOF +if terminal_input ${GRUB_TERMINAL_INPUT} ; then true ; else + # For backward compatibility with versions of terminal.mod that don't + # understand terminal_input + terminal ${GRUB_TERMINAL_INPUT} +fi +EOF + ;; +esac + +case x${GRUB_TERMINAL_OUTPUT} in + xgfxterm) + # Make the font accessible + prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}` + + # Pick a video backend + video_backend= + for i in vbe ; do + if test -e ${grub_prefix}/$i.mod ; then + video_backend=$i + break + fi + done + if ! [ "${video_backend}" ] ; then + echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 + fi + + cat << EOF +if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then + set gfxmode=${GRUB_GFXMODE} + insmod gfxterm + insmod ${video_backend} + if terminal_output gfxterm ; then true ; else + # For backward compatibility with versions of terminal.mod that don't + # understand terminal_output + terminal gfxterm + fi +fi +EOF + ;; + x) + # Just use the native terminal + ;; + x*) + cat << EOF +if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else + # For backward compatibility with versions of terminal.mod that don't + # understand terminal_output + terminal ${GRUB_TERMINAL_OUTPUT} +fi +EOF + ;; +esac diff --git a/util/grub.d/10_freebsd.in b/util/grub.d/10_freebsd.in new file mode 100644 index 0000000..61d5450 --- /dev/null +++ b/util/grub.d/10_freebsd.in @@ -0,0 +1,60 @@ +#! /bin/sh -e + +# grub-mkconfig helper script. +# Copyright (C) 2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +devices=/boot/devices.hints +if ! test -e ${devices} ; then + # not FreeBSD + exit 0 +fi + +if test -e /boot/kernel/kernel ; then + kfreebsd=/boot/kernel/kernel +fi + +if [ "x$kfreebsd" != "x" ] ; then + echo "Found kernel of FreeBSD: $kfreebsd" >&2 + + kfreebsd_basename=`basename $kfreebsd` + kfreebsd_dirname=`dirname $kfreebsd` + kfreebsd_rel_dirname=`make_system_path_relative_to_its_root $kfreebsd_dirname` + + devices_basename=`basename $devices` + devices_dirname=`dirname $devices` + devices_rel_dirname=`make_system_path_relative_to_its_root $devices_dirname` + + root_device=`basename ${GRUB_DEVICE}` + + # For "ufs" it's the same. Do we care about the others? + kfreebsd_fs=${GRUB_FS} + + cat << EOF +menuentry "FreeBSD" { +EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF + freebsd ${kfreebsd_rel_dirname}/${kfreebsd_basename} + freebsd_loadenv ${devices_rel_dirname}/${devices_basename} + set FreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${root_device} +} +EOF +fi diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in new file mode 100644 index 0000000..12d61b0 --- /dev/null +++ b/util/grub.d/10_hurd.in @@ -0,0 +1,85 @@ +#! /bin/sh -e + +# update-grub helper script. +# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=GNU +else + OS="${GRUB_DISTRIBUTOR} GNU/Hurd" +fi + +at_least_one=false +all_of_them=true + +# FIXME: add l4 here? +kernel= +for i in /boot/gnumach.gz /boot/gnumach ; do + if test -e $i ; then + basename=`basename $i` + dirname=`dirname $i` + rel_dirname=`make_system_path_relative_to_its_root $dirname` + echo "Found GNU Mach: $i" >&2 + kernel=${rel_dirname}/${basename} + at_least_one=true + fi +done + +# FIXME: This works for ext2. For other filesystems we might need special-casing +case "${GRUB_FS}" in + *fs) hurd_fs="${GRUB_FS}" ;; + *) hurd_fs="${GRUB_FS}fs" ;; +esac + +for i in /hurd/${hurd_fs}.static /hurd/exec ; do + if test -e "$i" ; then + echo "Found Hurd module: $i" >&2 + at_least_one=true + else + all_of_them=false + fi +done + +if ${at_least_one} ; then : ; else + # no hurd here, aborting silently + exit 0 +fi + +if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else + echo "Some Hurd stuff found, but not enough to boot." >&2 + exit 1 +fi + +cat << EOF +menuentry "${OS}" { +EOF +prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" +cat << EOF + multiboot ${kernel} root=device:${GRUB_DEVICE} + module /hurd/${hurd_fs}.static --readonly \\ + --multiboot-command-line='\${kernel-command-line}' \\ + --host-priv-port='\${host-port}' \\ + --device-master-port='\${device-port}' \\ + --exec-server-task='\${exec-task}' -T typed '\${root}' \\ + '\$(task-create)' '\$(task-resume)' + module /lib/ld.so.1 /hurd/exec '\$(exec-task=task-create)' +} +EOF diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in new file mode 100644 index 0000000..7cd5a9e --- /dev/null +++ b/util/grub.d/10_linux.in @@ -0,0 +1,158 @@ +#! /bin/sh -e + +# update-grub helper script. +# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=GNU/Linux +else + OS="${GRUB_DISTRIBUTOR} GNU/Linux" +fi + +# loop-AES arranges things so that /dev/loop/X can be our root device, but +# the initrds that Linux uses don't like that. +case ${GRUB_DEVICE} in + /dev/loop/*|/dev/loop[0-9]) + GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"` + ;; +esac + +if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ + || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then + LINUX_ROOT_DEVICE=${GRUB_DEVICE} +else + LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} +fi + +test_numeric () +{ + local a=$1 + local cmp=$2 + local b=$3 + if [ "$a" = "$b" ] ; then + case $cmp in + ge|eq|le) return 0 ;; + gt|lt) return 1 ;; + esac + fi + if [ "$cmp" = "lt" ] ; then + c=$a + a=$b + b=$c + fi + if (echo $a ; echo $b) | sort -n | head -n 1 | grep -qx $b ; then + return 0 + else + return 1 + fi +} + +test_gt () +{ + local a=`echo $1 | sed -e "s/vmlinu[zx]-//g"` + local b=`echo $2 | sed -e "s/vmlinu[zx]-//g"` + local cmp=gt + if [ "x$b" = "x" ] ; then + return 0 + fi + case $a:$b in + *.old:*.old) ;; + *.old:*) a=`echo -n $a | sed -e s/\.old$//g` ; cmp=gt ;; + *:*.old) b=`echo -n $b | sed -e s/\.old$//g` ; cmp=ge ;; + esac + test_numeric $a $cmp $b + return $? +} + +find_latest () +{ + local a="" + for i in $@ ; do + if test_gt "$i" "$a" ; then + a="$i" + fi + done + echo "$a" +} + +list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` + +while [ "x$list" != "x" ] ; do + linux=`find_latest $list` + echo "Found linux image: $linux" >&2 + basename=`basename $linux` + dirname=`dirname $linux` + rel_dirname=`make_system_path_relative_to_its_root $dirname` + version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` + alt_version=`echo $version | sed -e "s,\.old$,,g"` + linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" + + initrd= + for i in "initrd.img-${version}" "initrd-${version}.img" \ + "initrd.img-${alt_version}" "initrd-${alt_version}.img"; do + if test -e "${dirname}/${i}" ; then + initrd="$i" + break + fi + done + if test -n "${initrd}" ; then + echo "Found initrd image: ${dirname}/${initrd}" >&2 + else + # "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. + linux_root_device_thisversion=${GRUB_DEVICE} + fi + + cat << EOF +menuentry "${OS}, linux ${version}" { +EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF + linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} +EOF + if test -n "${initrd}" ; then + cat << EOF + initrd ${rel_dirname}/${initrd} +EOF + fi + cat << EOF +} +EOF + + cat << EOF +menuentry "${OS}, linux ${version} (single-user mode)" { +EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF + linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro single ${GRUB_CMDLINE_LINUX} +EOF + if test -n "${initrd}" ; then + cat << EOF + initrd ${rel_dirname}/${initrd} +EOF + fi + cat << EOF +} +EOF + + list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` +done diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in new file mode 100644 index 0000000..8877b15 --- /dev/null +++ b/util/grub.d/10_windows.in @@ -0,0 +1,83 @@ +#! /bin/sh -e + +# update-grub helper script. +# Copyright (C) 2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +case "`uname 2>/dev/null`" in + CYGWIN*) ;; + *) exit 0 ;; +esac + +# Try C: even if current system is on other partition. +case "$SYSTEMDRIVE" in + [Cc]:) dirlist="C:" ;; + [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;; + *) exit 0 ;; +esac + +get_os_name_from_boot_ini () +{ + # Fail if no or more than one partition. + test "`sed -n 's,^\(\(multi\|scsi\)[^=]*\)=.*$,\1,p' "$1" 2>/dev/null | \ + sort | uniq | wc -l`" = 1 || return 1 + + # Search 'default=PARTITION' + local part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` + test -n "$part" || return 1 + + # Search 'PARTITION="NAME" ...' + local name=`sed -n 's,\\\\,/,g;s,^'"$part"'="\([^"]*\)".*$,\1,p' "$1" | sed 1q` + test -n "$name" || return 1 + + echo "$name" +} + + +for dir in $dirlist ; do + + # Check for Vista bootmgr. + if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then + OS="Windows Vista bootmgr" + + # Check for NTLDR. + elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then + OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="Windows NT/2000/XP loader" + + else + continue + fi + + # Get boot /dev/ice. + dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue + + echo "Found $OS on $dir ($dev)" >&2 + cat << EOF +menuentry "$OS" { +EOF + + prepare_grub_to_access_device "$dev" | sed 's,^,\t,' + + cat << EOF + chainloader +1 +} +EOF +done + diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in new file mode 100644 index 0000000..429cc95 --- /dev/null +++ b/util/grub.d/30_os-prober.in @@ -0,0 +1,89 @@ +#! /bin/sh -e + +# update-grub helper script. +# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +if [ -z "`which os-prober 2> /dev/null`" -o -z "`which linux-boot-prober 2> /dev/null`" ] ; then + # missing os-prober and/or linux-boot-prober + exit 0 +fi + +OSPROBED="`os-prober 2> /dev/null | tr ' ' '^' | paste -s -d ' '`" +if [ -z "${OSPROBED}" ] ; then + # empty os-prober output, nothing doing + exit 0 +fi + +for OS in ${OSPROBED} ; do + DEVICE="`echo ${OS} | cut -d ':' -f 1`" + LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" + LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" + BOOT="`echo ${OS} | cut -d ':' -f 4`" + + if [ -z "${LONGNAME}" ] ; then + LONGNAME="${LABEL}" + fi + + echo "Found ${LONGNAME} on ${DEVICE}" >&2 + + case ${BOOT} in + chain) + CHAINROOT="`grub-probe --target=drive --device ${DEVICE} 2> /dev/null`" + + cat << EOF +menuentry "${LONGNAME} (on ${DEVICE})" { + set root=${CHAINROOT} + chainloader +1 +} +EOF + ;; + linux) + LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`" + + for LINUX in ${LINUXPROBED} ; do + LROOT="`echo ${LINUX} | cut -d ':' -f 1`" + LBOOT="`echo ${LINUX} | cut -d ':' -f 2`" + LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`" + LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`" + LINITRD="`echo ${LINUX} | cut -d ':' -f 5`" + LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`" + + LINUXROOT="`grub-probe --target=drive --device ${LBOOT} 2> /dev/null`" + + if [ -z "${LLABEL}" ] ; then + LLABEL="${LONGNAME}" + fi + + cat << EOF +menuentry "${LLABEL} (on ${DEVICE})" { + set root=${LINUXROOT} + linux ${LKERNEL} ${LPARAMS} +EOF + if [ -n "${LINITRD}" ] ; then + cat << EOF + initrd ${LINITRD} +EOF + fi + cat << EOF +} +EOF + done + ;; + hurd|*) + echo " ${LONGNAME} is not yet supported by grub-mkconfig." >&2 + ;; + esac +done diff --git a/util/grub.d/40_custom.in b/util/grub.d/40_custom.in new file mode 100644 index 0000000..e16d6e3 --- /dev/null +++ b/util/grub.d/40_custom.in @@ -0,0 +1,3 @@ +#!/bin/sh +exec tail -n +3 $0 +# This file is an example on how to add custom entries diff --git a/util/grub.d/README b/util/grub.d/README new file mode 100644 index 0000000..3ea109d --- /dev/null +++ b/util/grub.d/README @@ -0,0 +1,11 @@ + +All executable files in this directory are processed in shell expansion order. + + 00_*: Reserved for 00_header. + 10_*: Native boot entries. + 20_*: Third party apps (e.g. memtest86+). + +The number namespace in-between is configurable by system installer and/or +administrator. For example, you can add an entry to boot another OS as +01_otheros, 11_otheros, etc, depending on the position you want it to occupy in +the menu; and then adjust the default setting via /etc/default/grub. diff --git a/util/hostdisk.c b/util/hostdisk.c new file mode 100644 index 0000000..67a1233 --- /dev/null +++ b/util/hostdisk.c @@ -0,0 +1,940 @@ +/* biosdisk.c - emulate biosdisk */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +# include /* ioctl */ +# if !defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) +/* Maybe libc doesn't have large file support. */ +# include /* _llseek */ +# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ +# ifndef BLKFLSBUF +# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */ +# endif /* ! BLKFLSBUF */ +# include /* ioctl */ +# ifndef HDIO_GETGEO +# define HDIO_GETGEO 0x0301 /* get device geometry */ +/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is + defined. */ +struct hd_geometry +{ + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; +}; +# endif /* ! HDIO_GETGEO */ +# ifndef BLKGETSIZE64 +# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */ +# endif /* ! BLKGETSIZE64 */ +# ifndef MAJOR +# ifndef MINORBITS +# define MINORBITS 8 +# endif /* ! MINORBITS */ +# define MAJOR(dev) ((unsigned) ((dev) >> MINORBITS)) +# endif /* ! MAJOR */ +# ifndef FLOPPY_MAJOR +# define FLOPPY_MAJOR 2 +# endif /* ! FLOPPY_MAJOR */ +# ifndef LOOP_MAJOR +# define LOOP_MAJOR 7 +# endif /* ! LOOP_MAJOR */ +#endif /* __linux__ */ + +#ifdef __CYGWIN__ +# include +# include /* BLKGETSIZE64 */ +# include /* HDIO_GETGEO */ +# define MAJOR(dev) ((unsigned) ((dev) >> 16)) +# define FLOPPY_MAJOR 2 +#endif + +struct +{ + char *drive; + char *device; +} map[256]; + +#ifdef __linux__ +/* Check if we have devfs support. */ +static int +have_devfs (void) +{ + static int dev_devfsd_exists = -1; + + if (dev_devfsd_exists < 0) + { + struct stat st; + + dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0; + } + + return dev_devfsd_exists; +} +#endif /* __linux__ */ + +static int +find_grub_drive (const char *name) +{ + unsigned int i; + + if (name) + { + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) + if (map[i].drive && ! strcmp (map[i].drive, name)) + return i; + } + + return -1; +} + +static int +find_free_slot () +{ + unsigned int i; + + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) + if (! map[i].drive) + return i; + + return -1; +} + +static int +grub_util_biosdisk_iterate (int (*hook) (const char *name)) +{ + unsigned i; + + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) + if (map[i].drive && hook (map[i].drive)) + return 1; + + return 0; +} + +static grub_err_t +grub_util_biosdisk_open (const char *name, grub_disk_t disk) +{ + int drive; + struct stat st; + + drive = find_grub_drive (name); + if (drive < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, + "no mapping exists for `%s'", name); + + disk->has_partitions = 1; + disk->id = drive; + + /* Get the size. */ +#if defined(__MINGW32__) + { + grub_uint64_t size; + + size = grub_util_get_disk_size (map[drive].device); + + if (size % 512) + grub_util_error ("unaligned device size"); + + disk->total_sectors = size >> 9; + + grub_util_info ("the size of %s is %llu", name, disk->total_sectors); + + return GRUB_ERR_NONE; + } +#elif defined(__linux__) || defined(__CYGWIN__) + { + unsigned long long nr; + int fd; + + fd = open (map[drive].device, O_RDONLY); + if (fd == -1) + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); + + if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) + { + close (fd); + goto fail; + } + + if (ioctl (fd, BLKGETSIZE64, &nr)) + { + close (fd); + goto fail; + } + + close (fd); + disk->total_sectors = nr / 512; + + if (nr % 512) + grub_util_error ("unaligned device size"); + + grub_util_info ("the size of %s is %llu", name, disk->total_sectors); + + return GRUB_ERR_NONE; + } + + fail: + /* In GNU/Hurd, stat() will return the right size. */ +#elif !defined (__GNU__) +# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." +#endif + if (stat (map[drive].device, &st) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", map[drive].device); + + disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS; + + grub_util_info ("the size of %s is %lu", name, disk->total_sectors); + + return GRUB_ERR_NONE; +} + +#ifdef __linux__ +static int +linux_find_partition (char *dev, unsigned long sector) +{ + size_t len = strlen (dev); + const char *format; + char *p; + int i; + char real_dev[PATH_MAX]; + + strcpy(real_dev, dev); + + if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0) + { + p = real_dev + len - 4; + format = "part%d"; + } + else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9') + { + p = real_dev + len; + format = "p%d"; + } + else + { + p = real_dev + len; + format = "%d"; + } + + for (i = 1; i < 10000; i++) + { + int fd; + struct hd_geometry hdg; + + sprintf (p, format, i); + fd = open (real_dev, O_RDONLY); + if (fd == -1) + return 0; + + if (ioctl (fd, HDIO_GETGEO, &hdg)) + { + close (fd); + return 0; + } + + close (fd); + + if (hdg.start == sector) + { + strcpy (dev, real_dev); + return 1; + } + } + + return 0; +} +#endif /* __linux__ */ + +static int +open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) +{ + int fd; + +#ifdef O_LARGEFILE + flags |= O_LARGEFILE; +#endif +#ifdef O_SYNC + flags |= O_SYNC; +#endif +#ifdef O_FSYNC + flags |= O_FSYNC; +#endif +#ifdef O_BINARY + flags |= O_BINARY; +#endif + +#ifdef __linux__ + /* Linux has a bug that the disk cache for a whole disk is not consistent + with the one for a partition of the disk. */ + { + int is_partition = 0; + char dev[PATH_MAX]; + + strcpy (dev, map[disk->id].device); + if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0) + is_partition = linux_find_partition (dev, disk->partition->start); + + /* Open the partition. */ + grub_dprintf ("hostdisk", "opening the device `%s' in open_device()", dev); + fd = open (dev, flags); + if (fd < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); + return -1; + } + + /* Make the buffer cache consistent with the physical disk. */ + ioctl (fd, BLKFLSBUF, 0); + + if (is_partition) + sector -= disk->partition->start; + } +#else /* ! __linux__ */ + fd = open (map[disk->id].device, flags); + if (fd < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' in open_device()", map[disk->id].device); + return -1; + } +#endif /* ! __linux__ */ + +#if defined(__linux__) && (!defined(__GLIBC__) || \ + ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) + /* Maybe libc doesn't have large file support. */ + { + loff_t offset, result; + static int _llseek (uint filedes, ulong hi, ulong lo, + loff_t *res, uint wh); + _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, + loff_t *, res, uint, wh); + + offset = (loff_t) sector << GRUB_DISK_SECTOR_BITS; + if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); + close (fd); + return -1; + } + } +#else + { + off_t offset = (off_t) sector << GRUB_DISK_SECTOR_BITS; + + if (lseek (fd, offset, SEEK_SET) != offset) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot seek `%s'", map[disk->id].device); + close (fd); + return -1; + } + } +#endif + + return fd; +} + +/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an + error occurs, otherwise return LEN. */ +static ssize_t +nread (int fd, char *buf, size_t len) +{ + ssize_t size = len; + + while (len) + { + ssize_t ret = read (fd, buf, len); + + if (ret <= 0) + { + if (errno == EINTR) + continue; + else + return ret; + } + + len -= ret; + buf += ret; + } + + return size; +} + +/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an + error occurs, otherwise return LEN. */ +static ssize_t +nwrite (int fd, const char *buf, size_t len) +{ + ssize_t size = len; + + while (len) + { + ssize_t ret = write (fd, buf, len); + + if (ret <= 0) + { + if (errno == EINTR) + continue; + else + return ret; + } + + len -= ret; + buf += ret; + } + + return size; +} + +static grub_err_t +grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + int fd; + + fd = open_device (disk, sector, O_RDONLY); + if (fd < 0) + return grub_errno; + +#ifdef __linux__ + if (sector == 0 && size > 1) + { + /* Work around a bug in Linux ez remapping. Linux remaps all + sectors that are read together with the MBR in one read. It + should only remap the MBR, so we split the read in two + parts. -jochen */ + if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE) + { + grub_error (GRUB_ERR_READ_ERROR, "cannot read `%s'", map[disk->id].device); + close (fd); + return grub_errno; + } + + buf += GRUB_DISK_SECTOR_SIZE; + size--; + } +#endif /* __linux__ */ + + if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); + + close (fd); + return grub_errno; +} + +static grub_err_t +grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +{ + int fd; + + fd = open_device (disk, sector, O_WRONLY); + if (fd < 0) + return grub_errno; + + if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS) + != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) + grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device); + + close (fd); + return grub_errno; +} + +static struct grub_disk_dev grub_util_biosdisk_dev = + { + .name = "biosdisk", + .id = GRUB_DISK_DEVICE_BIOSDISK_ID, + .iterate = grub_util_biosdisk_iterate, + .open = grub_util_biosdisk_open, + .close = 0, + .read = grub_util_biosdisk_read, + .write = grub_util_biosdisk_write, + .next = 0 + }; + +static void +read_device_map (const char *dev_map) +{ + FILE *fp; + char buf[1024]; /* XXX */ + int lineno = 0; + struct stat st; + + auto void show_error (const char *msg); + void show_error (const char *msg) + { + grub_util_error ("%s:%d: %s", dev_map, lineno, msg); + } + + fp = fopen (dev_map, "r"); + if (! fp) + grub_util_error ("Cannot open `%s'", dev_map); + + while (fgets (buf, sizeof (buf), fp)) + { + char *p = buf; + char *e; + int drive; + + lineno++; + + /* Skip leading spaces. */ + while (*p && isspace (*p)) + p++; + + /* If the first character is `#' or NUL, skip this line. */ + if (*p == '\0' || *p == '#') + continue; + + if (*p != '(') + show_error ("No open parenthesis found"); + + p++; + /* Find a free slot. */ + drive = find_free_slot (); + if (drive < 0) + show_error ("Map table size exceeded"); + + e = p; + p = strchr (p, ')'); + if (! p) + show_error ("No close parenthesis found"); + + map[drive].drive = xmalloc (p - e + sizeof ('\0')); + strncpy (map[drive].drive, e, p - e + sizeof ('\0')); + map[drive].drive[p - e] = '\0'; + + p++; + /* Skip leading spaces. */ + while (*p && isspace (*p)) + p++; + + if (*p == '\0') + show_error ("No filename found"); + + /* NUL-terminate the filename. */ + e = p; + while (*e && ! isspace (*e)) + e++; + *e = '\0'; + + if (stat (p, &st) == -1) + { + free (map[drive].drive); + map[drive].drive = NULL; + grub_util_info ("Cannot stat `%s', skipping", p); + continue; + } + +#ifdef __linux__ + /* On Linux, the devfs uses symbolic links horribly, and that + confuses the interface very much, so use realpath to expand + symbolic links. */ + map[drive].device = xmalloc (PATH_MAX); + if (! realpath (p, map[drive].device)) + grub_util_error ("Cannot get the real path of `%s'", p); +#else + map[drive].device = xstrdup (p); +#endif + } + + fclose (fp); +} + +void +grub_util_biosdisk_init (const char *dev_map) +{ + read_device_map (dev_map); + grub_disk_dev_register (&grub_util_biosdisk_dev); +} + +void +grub_util_biosdisk_fini (void) +{ + unsigned i; + + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) + { + if (map[i].drive) + free (map[i].drive); + if (map[i].device) + free (map[i].device); + map[i].drive = map[i].device = NULL; + } + + grub_disk_dev_unregister (&grub_util_biosdisk_dev); +} + +static char * +make_device_name (int drive, int dos_part, int bsd_part) +{ + char *p; + + p = xmalloc (30); + sprintf (p, "%s", map[drive].drive); + + if (dos_part >= 0) + sprintf (p + strlen (p), ",%d", dos_part + 1); + + if (bsd_part >= 0) + sprintf (p + strlen (p), ",%c", bsd_part + 'a'); + + return p; +} + +static char * +convert_system_partition_to_system_disk (const char *os_dev) +{ +#if defined(__linux__) + char *path = xmalloc (PATH_MAX); + if (! realpath (os_dev, path)) + return 0; + + if (strncmp ("/dev/", path, 5) == 0) + { + char *p = path + 5; + + /* If this is an IDE disk. */ + if (strncmp ("ide/", p, 4) == 0) + { + p = strstr (p, "part"); + if (p) + strcpy (p, "disc"); + + return path; + } + + /* If this is a SCSI disk. */ + if (strncmp ("scsi/", p, 5) == 0) + { + p = strstr (p, "part"); + if (p) + strcpy (p, "disc"); + + return path; + } + + /* If this is a DAC960 disk. */ + if (strncmp ("rd/c", p, 4) == 0) + { + /* /dev/rd/c[0-9]+d[0-9]+(p[0-9]+)? */ + p = strchr (p, 'p'); + if (p) + *p = '\0'; + + return path; + } + + /* If this is a CCISS disk. */ + if (strncmp ("cciss/c", p, sizeof ("cciss/c") - 1) == 0) + { + /* /dev/cciss/c[0-9]+d[0-9]+(p[0-9]+)? */ + p = strchr (p, 'p'); + if (p) + *p = '\0'; + + return path; + } + + /* If this is a Compaq Intelligent Drive Array. */ + if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0) + { + /* /dev/ida/c[0-9]+d[0-9]+(p[0-9]+)? */ + p = strchr (p, 'p'); + if (p) + *p = '\0'; + + return path; + } + + /* If this is an I2O disk. */ + if (strncmp ("i2o/hd", p, sizeof ("i2o/hd") - 1) == 0) + { + /* /dev/i2o/hd[a-z]([0-9]+)? */ + p[sizeof ("i2o/hda") - 1] = '\0'; + return path; + } + + /* If this is a MultiMediaCard (MMC). */ + if (strncmp ("mmcblk", p, sizeof ("mmcblk") - 1) == 0) + { + /* /dev/mmcblk[0-9]+(p[0-9]+)? */ + p = strchr (p, 'p'); + if (p) + *p = '\0'; + + return path; + } + + /* If this is an IDE, SCSI or Virtio disk. */ + if ((strncmp ("hd", p, 2) == 0 + || strncmp ("vd", p, 2) == 0 + || strncmp ("sd", p, 2) == 0) + && p[2] >= 'a' && p[2] <= 'z') + { + /* /dev/[hsv]d[a-z][0-9]* */ + p[3] = '\0'; + return path; + } + + /* If this is a Xen virtual block device. */ + if ((strncmp ("xvd", p, 3) == 0) && p[3] >= 'a' && p[3] <= 'z') + { + /* /dev/xvd[a-z][0-9]* */ + p[4] = '\0'; + return path; + } + } + + return path; + +#elif defined(__GNU__) + char *path = xstrdup (os_dev); + if (strncmp ("/dev/sd", path, 7) == 0 || strncmp ("/dev/hd", path, 7) == 0) + { + char *p = strchr (path + 7, 's'); + if (p) + *p = '\0'; + } + return path; + +#elif defined(__CYGWIN__) + char *path = xstrdup (os_dev); + if (strncmp ("/dev/sd", path, 7) == 0 && 'a' <= path[7] && path[7] <= 'z') + path[8] = 0; + return path; + +#else +# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly." + return xstrdup (os_dev); +#endif +} + +static int +find_system_device (const char *os_dev) +{ + int i; + char *os_disk; + + os_disk = convert_system_partition_to_system_disk (os_dev); + if (! os_disk) + return -1; + + for (i = 0; i < (int) (sizeof (map) / sizeof (map[0])); i++) + if (map[i].device && strcmp (map[i].device, os_disk) == 0) + { + free (os_disk); + return i; + } + + free (os_disk); + return -1; +} + +char * +grub_util_biosdisk_get_grub_dev (const char *os_dev) +{ + struct stat st; + int drive; + + if (stat (os_dev, &st) < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", os_dev); + return 0; + } + + drive = find_system_device (os_dev); + if (drive < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "no mapping exists for `%s'", os_dev); + return 0; + } + + if (! S_ISBLK (st.st_mode)) + return make_device_name (drive, -1, -1); + +#if defined(__linux__) || defined(__CYGWIN__) + /* Linux counts partitions uniformly, whether a BSD partition or a DOS + partition, so mapping them to GRUB devices is not trivial. + Here, get the start sector of a partition by HDIO_GETGEO, and + compare it with each partition GRUB recognizes. + + Cygwin /dev/sdXN emulation uses Windows partition mapping. It + does not count the extended partition and missing primary + partitions. Use same method as on Linux here. */ + { + char *name; + grub_disk_t disk; + int fd; + struct hd_geometry hdg; + int dos_part = -1; + int bsd_part = -1; + auto int find_partition (grub_disk_t disk, + const grub_partition_t partition); + + int find_partition (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t partition) + { + struct grub_pc_partition *pcdata = NULL; + + if (strcmp (partition->partmap->name, "pc_partition_map") == 0) + pcdata = partition->data; + + if (pcdata) + { + if (pcdata->bsd_part < 0) + grub_util_info ("DOS partition %d starts from %lu", + pcdata->dos_part, partition->start); + else + grub_util_info ("BSD partition %d,%c starts from %lu", + pcdata->dos_part, pcdata->bsd_part + 'a', + partition->start); + } + else + { + grub_util_info ("Partition %d starts from %lu", + partition->index, partition->start); + } + + if (hdg.start == partition->start) + { + if (pcdata) + { + dos_part = pcdata->dos_part; + bsd_part = pcdata->bsd_part; + } + else + { + dos_part = partition->index; + bsd_part = -1; + } + return 1; + } + + return 0; + } + + name = make_device_name (drive, -1, -1); + + if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) + return name; + + fd = open (os_dev, O_RDONLY); + if (fd == -1) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); + free (name); + return 0; + } + + if (ioctl (fd, HDIO_GETGEO, &hdg)) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get geometry of `%s'", os_dev); + close (fd); + free (name); + return 0; + } + + close (fd); + + grub_util_info ("%s starts from %lu", os_dev, hdg.start); + + if (hdg.start == 0) + return name; + + grub_util_info ("opening the device %s", name); + disk = grub_disk_open (name); + free (name); + + if (! disk) + return 0; + + grub_partition_iterate (disk, find_partition); + if (grub_errno != GRUB_ERR_NONE) + { + grub_disk_close (disk); + return 0; + } + + if (dos_part < 0) + { + grub_disk_close (disk); + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot find the partition of `%s'", os_dev); + return 0; + } + + return make_device_name (drive, dos_part, bsd_part); + } + +#elif defined(__GNU__) + /* GNU uses "/dev/[hs]d[0-9]+(s[0-9]+[a-z]?)?". */ + { + char *p; + int dos_part = -1; + int bsd_part = -1; + + p = strrchr (os_dev, 's'); + if (p) + { + long int n; + char *q; + + p++; + n = strtol (p, &q, 10); + if (p != q && n != LONG_MIN && n != LONG_MAX) + { + dos_part = (int) n; + + if (*q >= 'a' && *q <= 'g') + bsd_part = *q - 'a'; + } + } + + return make_device_name (drive, dos_part, bsd_part); + } + +#else +# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly." + return make_device_name (drive, -1, -1); +#endif +} diff --git a/util/hostfs.c b/util/hostfs.c new file mode 100644 index 0000000..d68c36f --- /dev/null +++ b/util/hostfs.c @@ -0,0 +1,168 @@ +/* hostfs.c - Dummy filesystem to provide access to the hosts filesystem */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#ifndef DT_DIR +/* dirent.d_type is a BSD extension, not part of POSIX */ +#include +#include + +static int +is_dir (const char *path, const char *name) +{ + int len1 = strlen(path); + int len2 = strlen(name); + + char pathname[len1 + 1 + len2 + 1 + 13]; + strcpy (pathname, path); + + /* Avoid UNC-path "//name" on Cygwin. */ + if (len1 > 0 && pathname[len1 - 1] != '/') + strcat (pathname, "/"); + + strcat (pathname, name); + + struct stat st; + if (stat (pathname, &st)) + return 0; + return S_ISDIR (st.st_mode); +} +#endif + +static grub_err_t +grub_hostfs_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, int dir)) +{ + DIR *dir; + + /* Check if the disk is our dummy disk. */ + if (grub_strcmp (device->disk->name, "host")) + return grub_error (GRUB_ERR_BAD_FS, "not a hostfs"); + + dir = opendir (path); + if (! dir) + return grub_error (GRUB_ERR_BAD_FILENAME, + "can't open the hostfs directory `%s'", path); + + while (1) + { + struct dirent *de; + + de = readdir (dir); + if (! de) + break; + +#ifdef DT_DIR + hook (de->d_name, de->d_type == DT_DIR); +#else + hook (de->d_name, is_dir (path, de->d_name)); +#endif + } + + closedir (dir); + + return GRUB_ERR_NONE; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_hostfs_open (struct grub_file *file, const char *name) +{ + FILE *f; + + f = fopen (name, "rb"); + if (! f) + return grub_error (GRUB_ERR_BAD_FILENAME, + "can't open `%s'", name); + file->data = f; + +#ifdef __MINGW32__ + file->size = grub_util_get_disk_size (name); +#else + fseeko (f, 0, SEEK_END); + file->size = ftello (f); + fseeko (f, 0, SEEK_SET); +#endif + + return GRUB_ERR_NONE; +} + +static grub_ssize_t +grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len) +{ + FILE *f; + + f = (FILE *) file->data; + fseeko (f, file->offset, SEEK_SET); + int s = fread (buf, 1, len, f); + + return s; +} + +static grub_err_t +grub_hostfs_close (grub_file_t file) +{ + FILE *f; + + f = (FILE *) file->data; + fclose (f); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_hostfs_label (grub_device_t device __attribute ((unused)), + char **label __attribute ((unused))) +{ + *label = 0; + return GRUB_ERR_NONE; +} + +static struct grub_fs grub_hostfs_fs = + { + .name = "hostfs", + .dir = grub_hostfs_dir, + .open = grub_hostfs_open, + .read = grub_hostfs_read, + .close = grub_hostfs_close, + .label = grub_hostfs_label, + .next = 0 + }; + + + +GRUB_MOD_INIT(hostfs) +{ + grub_fs_register (&grub_hostfs_fs); +} + +GRUB_MOD_FINI(hostfs) +{ + grub_fs_unregister (&grub_hostfs_fs); +} diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in new file mode 100644 index 0000000..a5f97e3 --- /dev/null +++ b/util/i386/efi/grub-install.in @@ -0,0 +1,211 @@ +#! /bin/sh + +# Install GRUB on your EFI partition. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +sbindir=@sbindir@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ +platform=@platform@ +pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` + +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` +grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +rootdir= +grub_prefix=`echo /boot/grub | sed ${transform}` +modules= + +no_floppy= +force_lba= +recheck=no +debug=no + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --grub-mkdevicemap=*) + grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + --grub-probe=*) + grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-floppy) + no_floppy="--no-floppy" ;; + --recheck) + recheck=yes ;; + # This is an undocumented feature... + --debug) + debug=yes ;; + *) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + esac +done + +# If the debugging feature is enabled, print commands. +if test $debug = yes; then + set -x +fi + +# Initialize these directories here, since ROOTDIR was initialized. +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + bootdir=${rootdir} + ;; +*) + # Use /boot/grub by default. + bootdir=${rootdir}/boot + ;; +esac + +grubdir=${bootdir}/`echo grub | sed ${transform}` +device_map=${grubdir}/device.map + +# Check if GRUB is installed. +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +set $grub_mkdevicemap dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +# Create the GRUB directory if it is not present. +test -d "$bootdir" || mkdir "$bootdir" || exit 1 +test -d "$grubdir" || mkdir "$grubdir" || exit 1 + +# If --recheck is specified, remove the device map, if present. +if test $recheck = yes; then + rm -f $device_map +fi + +# Create the device map file if it is not present. +if test -f "$device_map"; then + : +else + # Create a safe temporary file. + test -n "$mklog" && log_file=`$mklog` + + $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 +fi + +# Make sure that there is no duplicated entry. +tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ + | sort | uniq -d | sed -n 1p` +if test -n "$tmp"; then + echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 + exit 1 +fi + +# Copy the GRUB images to the GRUB directory. +for file in ${grubdir}/*.mod ${grubdir}/*.lst; do + if test -f $file && [ "`basename $file`" != menu.lst ]; then + rm -f $file || exit 1 + fi +done +for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do + cp -f $file ${grubdir} || exit 1 +done + +# Create the core image. First, auto-detect the filesystem module. +fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}` +if test "x$fs_module" = xfat; then :; else + echo "${grubdir} doesn't look like an EFI partition." 1>&2 + exit 1 +fi + +# Then the partition map module. In order to support partition-less media, +# this command is allowed to fail (--target=fs already grants us that the +# filesystem will be accessible). +partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null` + +# Device abstraction module, if any (lvm, raid). +devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` + +# The order in this list is critical. Be careful when modifying it. +modules="$modules $fs_module $partmap_module $devabstraction_module" + +$grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1 + +# Prompt the user to check if the device map is correct. +echo "Installation finished. No error reported." +echo "This is the contents of the device map $device_map." +echo "Check if this is correct or not. If any of the lines is incorrect," +echo "fix it and re-run the script \`grub-install'." +echo + +cat $device_map + +# Bye. +exit 0 diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c new file mode 100644 index 0000000..36ea31f --- /dev/null +++ b/util/i386/efi/grub-mkimage.c @@ -0,0 +1,1124 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + +typedef Elf32_Word Elf_Word; +typedef Elf32_Addr Elf_Addr; +typedef Elf32_Ehdr Elf_Ehdr; +typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Sym Elf_Sym; +typedef Elf32_Half Elf_Half; +typedef Elf32_Off Elf_Off; +typedef Elf32_Section Elf_Section; +typedef Elf32_Rel Elf_Rel; +typedef Elf32_Rela Elf_Rela; + +#define ELF_R_SYM ELF32_R_SYM +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_INFO ELF32_R_INFO + +#define grub_le_to_cpu grub_le_to_cpu32 + +#elif GRUB_TARGET_SIZEOF_VOID_P == 8 + +typedef Elf64_Word Elf_Word; +typedef Elf64_Addr Elf_Addr; +typedef Elf64_Ehdr Elf_Ehdr; +typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Sym Elf_Sym; +typedef Elf64_Half Elf_Half; +typedef Elf64_Off Elf_Off; +typedef Elf64_Section Elf_Section; +typedef Elf64_Rel Elf_Rel; +typedef Elf64_Rela Elf_Rela; + +#define ELF_R_SYM ELF64_R_SYM +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_INFO ELF64_R_INFO + +#define grub_le_to_cpu grub_le_to_cpu64 + +#endif + +static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + +static inline Elf_Addr +align_address (Elf_Addr addr, unsigned alignment) +{ + return (addr + alignment - 1) & ~(alignment - 1); +} + +static inline Elf_Addr +align_pe32_section (Elf_Addr addr) +{ + return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT); +} + +/* Read the whole kernel image. Return the pointer to a read image, + and store the size in bytes in *SIZE. */ +static char * +read_kernel_module (const char *dir, char *prefix, size_t *size) +{ + char *kernel_image; + char *kernel_path; + + kernel_path = grub_util_get_path (dir, "kernel.mod"); + *size = grub_util_get_image_size (kernel_path); + kernel_image = grub_util_read_image (kernel_path); + free (kernel_path); + + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + grub_util_error ("prefix too long"); + + strcpy (kernel_image + sizeof (Elf_Ehdr) + GRUB_KERNEL_MACHINE_PREFIX, prefix); + + return kernel_image; +} + +/* Return if the ELF header is valid. */ +static int +check_elf_header (Elf_Ehdr *e, size_t size) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_version != grub_cpu_to_le32 (EV_CURRENT) + || ((e->e_ident[EI_CLASS] != ELFCLASS32) && + (e->e_ident[EI_CLASS] != ELFCLASS64)) + || e->e_ident[EI_DATA] != ELFDATA2LSB + || ((e->e_machine != grub_cpu_to_le16 (EM_386)) && + (e->e_machine != grub_cpu_to_le16 (EM_X86_64)))) + return 0; + + return 1; +} + +/* Return the starting address right after the header, + aligned by the section alignment. Allocate 4 section tables for + .text, .data, .reloc, and mods. */ +static Elf_Addr +get_starting_section_address (void) +{ + return align_pe32_section (sizeof (struct grub_pe32_header) + + 4 * sizeof (struct grub_pe32_section_table)); +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +is_text_section (Elf_Shdr *s) +{ + return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)) + == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +is_data_section (Elf_Shdr *s) +{ + return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC) + && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR))); +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = get_starting_section_address (); + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_text_section (s)) + { + Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); + const char *name = strtab + grub_le_to_cpu32 (s->sh_name); + + if (align) + current_address = align_address (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_le_to_cpu32 (s->sh_size); + } + + current_address = align_pe32_section (current_address); + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s)) + { + Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); + const char *name = strtab + grub_le_to_cpu32 (s->sh_name); + + if (align) + current_address = align_address (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_le_to_cpu32 (s->sh_size); + } + + return section_addresses; +} + +/* Return the symbol table section, if any. */ +static Elf_Shdr * +find_symtab_section (Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections) +{ + int i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB)) + return s; + + return 0; +} + +/* Return the address of the string table. */ +static const char * +find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize) +{ + Elf_Shdr *s; + char *strtab; + + s = (Elf_Shdr *) ((char *) sections + + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset); + return strtab; +} + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_le_to_cpu32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset); + + symtab_size = grub_le_to_cpu32 (symtab_section->sh_size); + sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize); + symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_le_to_cpu32 (sym->st_name); + + index = grub_le_to_cpu16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_le_to_cpu32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_le_to_cpu32 (s->sh_offset) + + i * grub_le_to_cpu32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +{ + return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_le_to_cpu32 (s->sh_link) + * section_entsize)); + target_section_index = grub_le_to_cpu32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_le_to_cpu32 (s->sh_name), + strtab + grub_le_to_cpu32 (target_section->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target, *value; + + offset = grub_le_to_cpu (r->r_offset); + target = get_target_address (e, target_section, offset); + info = grub_le_to_cpu (r->r_info); + sym_addr = get_symbol_address (e, symtab_section, + ELF_R_SYM (info)); + + value = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ? + (Elf_Addr *) &r->r_addend : target; + + switch (ELF_R_TYPE (info)) + { +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*value) + + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*value) + + sym_addr + - target_section_addr - offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + +#else + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*value) + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_cpu_to_le64 (grub_le_to_cpu64 (*value) + + sym_addr + - target_section_addr - offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_cpu_to_le64 (grub_le_to_cpu64 (*value) + + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + +#endif + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +void +write_padding (FILE *out, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) + if (fputc (0, out) == EOF) + grub_util_error ("padding failed"); +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +Elf_Addr +add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + FILE *out) +{ + struct grub_pe32_fixup_block *b = *block; + + /* First, check if it is necessary to write out the current block. */ + if (b) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((align_pe32_section (next_address) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_cpu_to_le32 (b->page_rva); + b->block_size = grub_cpu_to_le32 (b->block_size); + if (fwrite (b, size, 1, out) != 1) + grub_util_error ("write failed"); + free (b); + *block = b = 0; + } + } + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! b) + { + *block = b = xmalloc (sizeof (*b) + 2 * 0x1000); + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_cpu_to_le16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Write out zeros to make space for the header. */ +static Elf_Addr +make_header_space (FILE *out) +{ + Elf_Addr addr; + + addr = get_starting_section_address (); + write_padding (out, addr); + + return addr; +} + +/* Write text sections. */ +static Elf_Addr +write_text_sections (FILE *out, Elf_Addr current_address, + Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + Elf_Addr addr; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_text_section (s)) + { + Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); + Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); + Elf_Word size = grub_le_to_cpu32 (s->sh_size); + const char *name = strtab + grub_le_to_cpu32 (s->sh_name); + + if (align) + { + addr = align_address (current_address, align); + if (current_address != addr) + { + grub_util_info ("padding %d bytes for the ELF section alignment", + addr - current_address); + write_padding (out, addr - current_address); + current_address = addr; + } + } + + grub_util_info ("writing the text section %s at 0x%x", + name, current_address); + + if (fwrite ((char *) e + offset, size, 1, out) != 1) + grub_util_error ("write failed"); + + current_address += size; + } + + addr = align_pe32_section (current_address); + if (addr != current_address) + { + grub_util_info ("padding %d bytes for the PE32 section alignment", + addr - current_address); + write_padding (out, addr - current_address); + } + + return addr; +} + +/* Write data sections. */ +static Elf_Addr +write_data_sections (FILE *out, Elf_Addr current_address, + Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + Elf_Addr addr; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s)) + { + Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); + Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); + Elf_Word size = grub_le_to_cpu32 (s->sh_size); + const char *name = strtab + grub_le_to_cpu32 (s->sh_name); + + if (align) + { + addr = align_address (current_address, align); + if (current_address != addr) + { + grub_util_info ("padding %d bytes for the ELF section alignment", + addr - current_address); + write_padding (out, addr - current_address); + current_address = addr; + } + } + + grub_util_info ("writing the data section %s at 0x%x", + name, current_address); + + if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS)) + write_padding (out, size); + else + if (fwrite ((char *) e + offset, size, 1, out) != 1) + grub_util_error ("write failed"); + + current_address += size; + } + + addr = align_pe32_section (current_address); + if (addr != current_address) + { + grub_util_info ("padding %d bytes for the PE32 section alignment", + addr - current_address); + write_padding (out, addr - current_address); + } + + return addr; +} + +/* Write modules. */ +static Elf_Addr +make_mods_section (FILE *out, Elf_Addr current_address, + const char *dir, char *mods[]) +{ + struct grub_util_path_list *path_list; + grub_size_t total_module_size; + struct grub_util_path_list *p; + struct grub_module_info modinfo; + Elf_Addr addr; + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + total_module_size = sizeof (struct grub_module_info); + for (p = path_list; p; p = p->next) + { + total_module_size += (grub_util_get_image_size (p->name) + + sizeof (struct grub_module_header)); + } + + grub_util_info ("the total module size is 0x%x", total_module_size); + + modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC); + modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo)); + modinfo.size = grub_cpu_to_le32 (total_module_size); + + if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1) + grub_util_error ("write failed"); + + for (p = path_list; p; p = p->next) + { + struct grub_module_header header; + size_t mod_size; + char *mod_image; + + grub_util_info ("adding module %s", p->name); + + mod_size = grub_util_get_image_size (p->name); + header.type = grub_cpu_to_le32 (OBJ_TYPE_ELF); + header.size = grub_cpu_to_le32 (mod_size + sizeof (header)); + + mod_image = grub_util_read_image (p->name); + + if (fwrite (&header, sizeof (header), 1, out) != 1 + || fwrite (mod_image, mod_size, 1, out) != 1) + grub_util_error ("write failed"); + + free (mod_image); + } + + for (p = path_list; p; ) + { + struct grub_util_path_list *q; + + q = p->next; + free (p); + p = q; + } + + current_address += total_module_size; + + addr = align_pe32_section (current_address); + if (addr != current_address) + { + grub_util_info ("padding %d bytes for the PE32 section alignment", + addr - current_address); + write_padding (out, addr - current_address); + } + + return addr; +} + +/* Make a .reloc section. */ +static Elf_Addr +make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + struct grub_pe32_fixup_block *fixup_block = 0; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&fixup_block, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + out); + } +#else + if ((ELF_R_TYPE (info) == R_X86_64_64) || + (ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&fixup_block, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + out); + } +#endif + } + } + + current_address = add_fixup_entry (&fixup_block, 0, 0, 1, + current_address, out); + + return current_address; +} + +/* Create the header. */ +static void +make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address, + Elf_Addr mods_address, Elf_Addr reloc_address, + Elf_Addr end_address, Elf_Addr start_address) +{ + struct grub_pe32_header header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table text_section, data_section; + struct grub_pe32_section_table mods_section, reloc_section; + + /* The magic. */ + memset (&header, 0, sizeof (header)); + memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub)); + memcpy (header.signature, "PE\0\0", sizeof (header.signature)); + + /* The COFF file header. */ + c = &header.coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386); +#else + c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_X86_64); +#endif + + c->num_sections = grub_cpu_to_le16 (4); + c->time = grub_cpu_to_le32 (time (0)); + c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header)); + c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + | GRUB_PE32_32BIT_MACHINE +#endif + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header.optional_header; + o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_cpu_to_le32 (data_address - text_address); + o->data_size = grub_cpu_to_le32 (reloc_address - data_address); + o->bss_size = 0; + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (text_address); +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + o->data_base = grub_cpu_to_le32 (data_address); +#endif + o->image_base = 0; + o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT); + o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT); + o->image_size = grub_cpu_to_le32 (end_address); + o->header_size = grub_cpu_to_le32 (text_address); + o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_cpu_to_le32 (0x10000); + o->stack_commit_size = grub_cpu_to_le32 (0x10000); + o->heap_reserve_size = grub_cpu_to_le32 (0x10000); + o->heap_commit_size = grub_cpu_to_le32 (0x10000); + + o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address); + o->base_relocation_table.size = grub_cpu_to_le32 (end_address + - reloc_address); + + /* The sections. */ + memset (&text_section, 0, sizeof (text_section)); + strcpy (text_section.name, ".text"); + text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address); + text_section.virtual_address = grub_cpu_to_le32 (text_address); + text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address); + text_section.raw_data_offset = grub_cpu_to_le32 (text_address); + text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + + memset (&data_section, 0, sizeof (data_section)); + strcpy (data_section.name, ".data"); + data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address); + data_section.virtual_address = grub_cpu_to_le32 (data_address); + data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address); + data_section.raw_data_offset = grub_cpu_to_le32 (data_address); + data_section.characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + memset (&mods_section, 0, sizeof (mods_section)); + strcpy (mods_section.name, "mods"); + mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address); + mods_section.virtual_address = grub_cpu_to_le32 (mods_address); + mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address); + mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address); + mods_section.characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + memset (&reloc_section, 0, sizeof (reloc_section)); + strcpy (reloc_section.name, ".reloc"); + reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address); + reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address); + reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address); + reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address); + reloc_section.characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + + /* Write them out. */ + if (fseeko (out, 0, SEEK_SET) < 0) + grub_util_error ("seek failed"); + + if (fwrite (&header, sizeof (header), 1, out) != 1 + || fwrite (&text_section, sizeof (text_section), 1, out) != 1 + || fwrite (&data_section, sizeof (data_section), 1, out) != 1 + || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1 + || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1) + grub_util_error ("write failed"); +} + +/* Convert an ELF relocatable object into an EFI Application (PE32). */ +void +convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) +{ + char *kernel_image; + size_t kernel_size; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Off section_offset; + Elf_Half section_entsize; + Elf_Half num_sections; + Elf_Addr *section_addresses; + Elf_Shdr *symtab_section; + Elf_Addr start_address; + Elf_Addr text_address, data_address, reloc_address, mods_address; + Elf_Addr end_address; + + /* Get the kernel image and check the format. */ + kernel_image = read_kernel_module (dir, prefix, &kernel_size); + e = (Elf_Ehdr *) kernel_image; + if (! check_elf_header (e, kernel_size)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_cpu_to_le32 (e->e_shoff); + section_entsize = grub_cpu_to_le16 (e->e_shentsize); + num_sections = grub_cpu_to_le16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_image + section_offset); + strtab = find_strtab (e, sections, section_entsize); + + /* Relocate sections then symbols in the virtual address space. */ + section_addresses = locate_sections (sections, section_entsize, + num_sections, strtab); + + symtab_section = find_symtab_section (sections, + section_entsize, num_sections); + if (! symtab_section) + grub_util_error ("no symbol table"); + + start_address = relocate_symbols (e, sections, symtab_section, + section_addresses, section_entsize, + num_sections); + if (start_address == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab); + + /* Generate a PE32 image file. The strategy is to dump binary data first, + then fill up the header. */ + text_address = make_header_space (out); + data_address = write_text_sections (out, text_address, e, sections, + section_entsize, num_sections, + strtab); + mods_address = write_data_sections (out, data_address, e, sections, + section_entsize, num_sections, + strtab); + reloc_address = make_mods_section (out, mods_address, dir, mods); + end_address = make_reloc_section (out, reloc_address, e, section_addresses, + sections, section_entsize, num_sections, + strtab); + make_header (out, text_address, data_address, mods_address, + reloc_address, end_address, start_address); + + /* Clean up. */ + free (section_addresses); + free (kernel_image); +} + +static struct option options[] = + { + {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, + {"output", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + { 0, 0, 0, 0 } + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n"); + else + printf ("\ +Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\ +\n\ +Make a bootable image of GRUB.\n\ +\n\ +-d, --directory=DIR use images and modules under DIR [default=%s]\n\ +-p, --prefix=DIR set grub_prefix directory [default=%s]\n\ +-o, --output=FILE output a generated image to FILE\n\ +-h, --help display this message and exit\n\ +-V, --version print version information and exit\n\ +-v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + FILE *fp; + char *output = NULL; + char *dir = NULL; + char *prefix = NULL; + + progname = "grub-mkimage"; + + while (1) + { + int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); + if (c == -1) + break; + + switch (c) + { + case 'd': + if (dir) + free (dir); + dir = xstrdup (optarg); + break; + case 'h': + usage (0); + break; + case 'o': + if (output) + free (output); + output = xstrdup (optarg); + break; + case 'p': + if (prefix) + free (prefix); + prefix = xstrdup (optarg); + break; + case 'V': + printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + case 'v': + verbosity++; + break; + default: + usage (1); + break; + } + } + + if (! output) + usage (1); + + fp = fopen (output, "wb"); + if (! fp) + grub_util_error ("cannot open %s", output); + + convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); + + fclose (fp); + + return 0; +} diff --git a/util/i386/pc/grub-install.in b/util/i386/pc/grub-install.in new file mode 100644 index 0000000..ff1ed1e --- /dev/null +++ b/util/i386/pc/grub-install.in @@ -0,0 +1,314 @@ +#! /bin/sh + +# Install GRUB on your drive. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +sbindir=@sbindir@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ +platform=@platform@ +pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` + +grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` +if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` +else + grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +fi +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` +grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +rootdir= +grub_prefix=`echo /boot/grub | sed ${transform}` +modules= + +install_device= +no_floppy= +force_lba= +recheck=no +debug=no + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --grub-setup=*) + grub_setup=`echo "$option" | sed 's/--grub-setup=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --grub-mkdevicemap=*) + grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + --grub-probe=*) + grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-floppy) + no_floppy="--no-floppy" ;; + --recheck) + recheck=yes ;; + # This is an undocumented feature... + --debug) + debug=yes ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$install_device" != x; then + echo "More than one install_devices?" 1>&2 + usage + exit 1 + fi + install_device="${option}" ;; + esac +done + +# for make_system_path_relative_to_its_root() +. ${libdir}/grub/grub-mkconfig_lib + +if test "x$install_device" = x; then + echo "install_device not specified." 1>&2 + usage + exit 1 +fi + +# If the debugging feature is enabled, print commands. +setup_verbose= +if test $debug = yes; then + set -x + setup_verbose="--verbose" +fi + +# Initialize these directories here, since ROOTDIR was initialized. +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + bootdir=${rootdir} + ;; +*) + # Use /boot/grub by default. + bootdir=${rootdir}/boot + ;; +esac + +grubdir=${bootdir}/`echo grub | sed ${transform}` +device_map=${grubdir}/device.map + +grub_probe="${grub_probe} --device-map=${device_map}" + +# Check if GRUB is installed. +if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + set $grub_setup dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi +fi + +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +set $grub_mkdevicemap dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +# Create the GRUB directory if it is not present. +test -d "$bootdir" || mkdir "$bootdir" || exit 1 +test -d "$grubdir" || mkdir "$grubdir" || exit 1 + +# If --recheck is specified, remove the device map, if present. +if test $recheck = yes; then + rm -f $device_map +fi + +# Create the device map file if it is not present. +if test -f "$device_map"; then + : +else + # Create a safe temporary file. + test -n "$mklog" && log_file=`$mklog` + + $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 +fi + +# Make sure that there is no duplicated entry. +tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \ + | sort | uniq -d | sed -n 1p` +if test -n "$tmp"; then + echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 + exit 1 +fi + +# Copy the GRUB images to the GRUB directory. +for file in ${grubdir}/*.mod ${grubdir}/*.lst ${grubdir}/*.img; do + if test -f $file && [ "`basename $file`" != menu.lst ]; then + rm -f $file || exit 1 + fi +done +for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do + cp -f $file ${grubdir} || exit 1 +done +if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + for file in ${pkglibdir}/*.img; do + cp -f $file ${grubdir} || exit 1 + done +fi + +# Write device to a variable so we don't have to traverse /dev every time. +grub_device=`$grub_probe --target=device ${grubdir}` + +# Create the core image. First, auto-detect the filesystem module. +fs_module=`$grub_probe --target=fs --device ${grub_device}` +if test "x$fs_module" = x -a "x$modules" = x; then + echo "Auto-detection of a filesystem module failed." 1>&2 + echo "Please specify the module with the option \`--modules' explicitly." 1>&2 + exit 1 +fi + +# Then the partition map module. In order to support partition-less media, +# this command is allowed to fail (--target=fs already grants us that the +# filesystem will be accessible). +partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null` + +# Device abstraction module, if any (lvm, raid). +devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` + +# The order in this list is critical. Be careful when modifying it. +if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + modules="$modules biosdisk" +else + modules="$modules ata" +fi +modules="$modules $fs_module $partmap_module $devabstraction_module" + +prefix_drive= +if [ "x${devabstraction_module}" = "x" ] ; then + if echo "${install_device}" | grep -qx "(.*)" ; then + install_drive="${install_device}" + else + install_drive="`$grub_probe --target=drive --device ${install_device}`" + fi + grub_drive="`$grub_probe --target=drive --device ${grub_device}`" + + # Strip partition number + install_drive="`echo ${install_drive} | sed -e s/,[0-9]*//g`" + grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*//g`" + if [ "${target_cpu}-${platform}" != "i386-pc" ] ; then + # generic method (used on coreboot) + uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" + if [ "x${uuid}" = "x" ] ; then + echo "UUID needed on this platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + exit 1 + fi + prefix_drive="(UUID=${uuid})" + modules="$modules fs_uuid" + elif [ "x${grub_drive}" != "x${install_drive}" ] ; then + uuid="`$grub_probe --target=fs_uuid --device ${grub_device}`" + if [ "x${uuid}" = "x" ] ; then + echo "You attempted a cross-disk install, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2 + exit 1 + fi + prefix_drive="(UUID=${uuid})" + modules="$modules fs_uuid" + fi +else + prefix_drive=`$grub_probe --target=drive --device ${grub_device}` +fi + +relative_grubdir=`make_system_path_relative_to_its_root ${grubdir}` || exit 1 +if [ "x${relative_grubdir}" = "x" ] ; then + relative_grubdir=/ +fi + +if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then + $grub_mkimage --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + + # Now perform the installation. + $grub_setup ${setup_verbose} --directory=${grubdir} --device-map=${device_map} \ + ${install_device} || exit 1 +else + $grub_mkimage -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 +fi + +# Prompt the user to check if the device map is correct. +echo "Installation finished. No error reported." +echo "This is the contents of the device map $device_map." +echo "Check if this is correct or not. If any of the lines is incorrect," +echo "fix it and re-run the script \`grub-install'." +echo + +cat $device_map + +# Bye. +exit 0 diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c new file mode 100644 index 0000000..4625b6d --- /dev/null +++ b/util/i386/pc/grub-mkimage.c @@ -0,0 +1,397 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +#if defined(ENABLE_LZO) + +#if defined(HAVE_LZO_LZO1X_H) +# include +#elif defined(HAVE_LZO1X_H) +# include +#endif + +#elif defined(ENABLE_LZMA) + +#include + +#endif + +#if defined(ENABLE_LZO) + +static void +compress_kernel (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + lzo_uint size; + char *wrkmem; + + grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); + if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + grub_util_error ("the core image is too small"); + + if (lzo_init () != LZO_E_OK) + grub_util_error ("cannot initialize LZO"); + + *core_img = xmalloc (kernel_size + kernel_size / 64 + 16 + 3); + wrkmem = xmalloc (LZO1X_999_MEM_COMPRESS); + + memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); + + grub_util_info ("compressing the core image"); + if (lzo1x_999_compress ((const lzo_byte *) (kernel_img + + GRUB_KERNEL_MACHINE_RAW_SIZE), + kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, + (lzo_byte *) (*core_img + + GRUB_KERNEL_MACHINE_RAW_SIZE), + &size, wrkmem) + != LZO_E_OK) + grub_util_error ("cannot compress the kernel image"); + + free (wrkmem); + + *core_size = (size_t) size + GRUB_KERNEL_MACHINE_RAW_SIZE; +} + +#elif defined(ENABLE_LZMA) + +static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } +static void SzFree(void *p, void *address) { p = p; free(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static void +compress_kernel (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size = 5; + + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + + grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); + if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + grub_util_error ("the core image is too small"); + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); + + *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE; + if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE, + core_size, + (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE, + kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + grub_util_error ("cannot compress the kernel image"); + + *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; +} + +#endif + +static void +generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path) +{ + grub_addr_t module_addr = 0; + char *kernel_img, *boot_img, *core_img; + size_t kernel_size, boot_size, total_module_size, core_size, memdisk_size = 0; + char *kernel_path, *boot_path; + unsigned num; + size_t offset; + struct grub_util_path_list *path_list, *p, *next; + struct grub_module_info *modinfo; + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + kernel_path = grub_util_get_path (dir, "kernel.img"); + kernel_size = grub_util_get_image_size (kernel_path); + + total_module_size = sizeof (struct grub_module_info); + + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); + grub_util_info ("the size of memory disk is 0x%x", memdisk_size); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + for (p = path_list; p; p = p->next) + total_module_size += (grub_util_get_image_size (p->name) + + sizeof (struct grub_module_header)); + + grub_util_info ("the total module size is 0x%x", total_module_size); + + kernel_img = xmalloc (kernel_size + total_module_size); + grub_util_load_image (kernel_path, kernel_img); + + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + grub_util_error ("prefix too long"); + strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + + /* Fill in the grub_module_info structure. */ + modinfo = (struct grub_module_info *) (kernel_img + kernel_size); + modinfo->magic = GRUB_MODULE_MAGIC; + modinfo->offset = sizeof (struct grub_module_info); + modinfo->size = total_module_size; + + offset = kernel_size + sizeof (struct grub_module_info); + for (p = path_list; p; p = p->next) + { + struct grub_module_header *header; + size_t mod_size; + + mod_size = grub_util_get_image_size (p->name); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_cpu_to_le32 (OBJ_TYPE_ELF); + header->size = grub_cpu_to_le32 (mod_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (p->name, kernel_img + offset); + offset += mod_size; + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_cpu_to_le32 (OBJ_TYPE_MEMDISK); + header->size = grub_cpu_to_le32 (memdisk_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (memdisk_path, kernel_img + offset); + offset += memdisk_size; + } + + compress_kernel (kernel_img, kernel_size + total_module_size, + &core_img, &core_size); + + grub_util_info ("the core size is 0x%x", core_size); + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error ("the core image is too big"); + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + /* i386 is a little endian architecture. */ + *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) + = grub_cpu_to_le16 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + + module_addr = (path_list + ? (GRUB_BOOT_MACHINE_KERNEL_ADDR + GRUB_DISK_SECTOR_SIZE + + kernel_size) + : 0); + + grub_util_info ("the first module address is 0x%x", module_addr); + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) + = grub_cpu_to_le32 (total_module_size); + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) + = grub_cpu_to_le32 (kernel_size); + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) + = grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + + /* If we included a drive in our prefix, let GRUB know it doesn't have to + prepend the drive told by BIOS. */ + if (prefix[0] == '(') + { + *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + = grub_cpu_to_le32 (-2); + *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + = grub_cpu_to_le32 (-2); + } + + if (core_size > GRUB_MEMORY_MACHINE_UPPER - GRUB_MEMORY_MACHINE_LINK_ADDR) + grub_util_error ("Core image is too big (%p > %p)\n", core_size, + GRUB_MEMORY_MACHINE_UPPER - GRUB_MEMORY_MACHINE_LINK_ADDR); + + grub_util_write_image (core_img, core_size, out); + free (kernel_img); + free (core_img); + free (kernel_path); + + while (path_list) + { + next = path_list->next; + free ((void *) path_list->name); + free (path_list); + path_list = next; + } +} + + + +static struct option options[] = + { + {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, + {"memdisk", required_argument, 0, 'm'}, + {"output", required_argument, 0, 'o'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n"); + else + printf ("\ +Usage: grub-mkimage [OPTION]... [MODULES]\n\ +\n\ +Make a bootable image of GRUB.\n\ +\n\ + -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ + -m, --memdisk=FILE embed FILE as a memdisk image\n\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); + + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *output = NULL; + char *dir = NULL; + char *prefix = NULL; + char *memdisk = NULL; + FILE *fp = stdout; + + progname = "grub-mkimage"; + + while (1) + { + int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'o': + if (output) + free (output); + + output = xstrdup (optarg); + break; + + case 'd': + if (dir) + free (dir); + + dir = xstrdup (optarg); + break; + + case 'm': + if (memdisk) + free (memdisk); + + memdisk = xstrdup (optarg); + + if (prefix) + free (prefix); + + prefix = xstrdup ("(memdisk)/boot/grub"); + break; + + case 'h': + usage (0); + break; + + case 'p': + if (prefix) + free (prefix); + + prefix = xstrdup (optarg); + break; + + case 'V': + printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (output) + { + fp = fopen (output, "wb"); + if (! fp) + grub_util_error ("cannot open %s", output); + } + + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk); + + fclose (fp); + + if (dir) + free (dir); + + return 0; +} diff --git a/util/i386/pc/grub-mkrescue.in b/util/i386/pc/grub-mkrescue.in new file mode 100644 index 0000000..358b37b --- /dev/null +++ b/util/i386/pc/grub-mkrescue.in @@ -0,0 +1,176 @@ +#! /bin/sh -e + +# Make GRUB rescue image +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ +platform=@platform@ +pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` + +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +image_type=cdrom +input_dir=${pkglibdir} +emulation=none + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --overlay=*) + overlay=${overlay}${overlay:+ }`echo "$option" | sed 's/--overlay=//'` ;; + --pkglibdir=*) + input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --image-type=*) + image_type=`echo "$option" | sed 's/--image-type=//'` + case "$image_type" in + floppy|cdrom) ;; + *) + echo "Unknown image type \`$image_type'" 1>&2 + exit 1 ;; + esac ;; + --emulation=*) + emulation=`echo "$option" | sed 's/--emulation=//'` + case "$emulation" in + floppy|none) ;; + *) + echo "Unknown emulation type \`$emulation'" 1>&2 + exit 1 ;; + esac ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$output_image" != x; then + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + fi + output_image="${option}" ;; + esac +done + +if test "x$output_image" = x; then + usage + exit 1 +fi + +aux_dir=`mktemp -d` +mkdir -p ${aux_dir}/boot/grub + +cp ${input_dir}/*.mod \ + ${input_dir}/command.lst ${input_dir}/moddep.lst ${input_dir}/fs.lst \ + ${aux_dir}/boot/grub/ + +modules="biosdisk `cat ${input_dir}/partmap.lst` ${modules}" +for i in ${modules} ; do + echo "insmod $i" +done > ${aux_dir}/boot/grub/grub.cfg + +for d in ${overlay}; do + echo "Overlaying $d" + cp -dpR "${d}"/* "${aux_dir}"/ +done + +if [ "x${image_type}" = xfloppy -o "x${emulation}" = xfloppy ] ; then + # build memdisk + memdisk_img=`mktemp` + tar -C ${aux_dir} -cf ${memdisk_img} boot + rm -rf ${aux_dir} + + # build core.img + core_img=`mktemp` + ${grub_mkimage} -d ${input_dir}/ -m ${memdisk_img} -o ${core_img} memdisk tar + rm -f ${memdisk_img} + + # build floppy image + if [ "x${image_type}" = xcdrom ] ; then + floppy_dir=`mktemp -d` + floppy_img=${floppy_dir}/grub_floppy.img + else + floppy_img=${output_image} + fi + cat ${input_dir}/boot.img ${core_img} /dev/zero | dd bs=1024 count=1440 > ${floppy_img} + rm -f ${core_img} + + if [ "x${image_type}" = xcdrom ] ; then + # build iso image + genisoimage -b grub_floppy.img \ + -o ${output_image} -r -J ${floppy_dir} + rm -rf ${floppy_dir} + fi +else + # build core.img + core_img=`mktemp` + ${grub_mkimage} -d ${input_dir}/ -o ${core_img} biosdisk iso9660 + + # build grub_eltorito image + cat ${input_dir}/cdboot.img ${core_img} > ${aux_dir}/boot/grub/grub_eltorito + rm -f ${core_img} + + # build iso image + genisoimage -b boot/grub/grub_eltorito \ + -no-emul-boot -boot-load-size 4 -boot-info-table \ + -o ${output_image} -r -J ${aux_dir} + rm -rf ${aux_dir} +fi + +exit 0 diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c new file mode 100644 index 0000000..ccbb465 --- /dev/null +++ b/util/i386/pc/grub-setup.c @@ -0,0 +1,751 @@ +/* grub-setup.c - make GRUB usable */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +#define DEFAULT_BOOT_FILE "boot.img" +#define DEFAULT_CORE_FILE "core.img" + +/* This is the blocklist used in the diskboot image. */ +struct boot_blocklist +{ + grub_uint64_t start; + grub_uint16_t len; + grub_uint16_t segment; +} __attribute__ ((packed)); + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +grub_term_input_t +grub_term_get_current_input (void) +{ + return 0; +} + +grub_term_output_t +grub_term_get_current_output (void) +{ + return 0; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +static void +setup (const char *dir, + const char *boot_file, const char *core_file, + const char *root, const char *dest, int must_embed) +{ + char *boot_path, *core_path, *core_path_dev; + char *boot_img, *core_img; + size_t boot_size, core_size; + grub_uint16_t core_sectors; + grub_device_t root_dev, dest_dev; + grub_uint8_t *boot_drive, *root_drive; + grub_disk_addr_t *kernel_sector; + grub_uint16_t *boot_drive_check; + struct boot_blocklist *first_block, *block; + grub_int32_t *install_dos_part, *install_bsd_part; + grub_int32_t dos_part, bsd_part; + char *tmp_img; + int i; + grub_disk_addr_t first_sector; + grub_uint16_t current_segment + = GRUB_BOOT_MACHINE_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); + grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE; + grub_file_t file; + FILE *fp; + struct { grub_uint64_t start; grub_uint64_t end; } embed_region; + embed_region.start = embed_region.end = ~0UL; + int able_to_embed = 1; + + auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset, + unsigned length); + auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset, + unsigned length); + + auto int find_usable_region (grub_disk_t disk, + const grub_partition_t p); + int find_usable_region (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t p) + { + if (! strcmp (p->partmap->name, "pc_partition_map")) + { + struct grub_pc_partition *pcdata = p->data; + + /* There's always an embed region, and it starts right after the MBR. */ + embed_region.start = 1; + + /* For its end offset, include as many dummy partitions as we can. */ + if (! grub_pc_partition_is_empty (pcdata->dos_type) + && ! grub_pc_partition_is_bsd (pcdata->dos_type) + && embed_region.end > p->start) + embed_region.end = p->start; + } + else + { + struct grub_gpt_partentry *gptdata = p->data; + + /* If there's an embed region, it is in a dedicated partition. */ + if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16)) + { + embed_region.start = p->start; + embed_region.end = p->start + p->len; + + return 1; + } + } + + return 0; + } + + void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset, + unsigned length) + { + grub_util_info ("the first sector is <%llu,%u,%u>", + sector, offset, length); + + if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("The first sector of the core file is not sector-aligned"); + + first_sector = sector; + } + + void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset, + unsigned length) + { + struct boot_blocklist *prev = block + 1; + + grub_util_info ("saving <%llu,%u,%u> with the segment 0x%x", + sector, offset, length, (unsigned) current_segment); + + if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("Non-sector-aligned data is found in the core file"); + + if (block != first_block + && (grub_le_to_cpu64 (prev->start) + + grub_le_to_cpu16 (prev->len)) == sector) + prev->len = grub_cpu_to_le16 (grub_le_to_cpu16 (prev->len) + 1); + else + { + block->start = grub_cpu_to_le64 (sector); + block->len = grub_cpu_to_le16 (1); + block->segment = grub_cpu_to_le16 (current_segment); + + block--; + if (block->len) + grub_util_error ("The sectors of the core file are too fragmented"); + } + + last_length = length; + current_segment += GRUB_DISK_SECTOR_SIZE >> 4; + } + + /* Read the boot image by the OS service. */ + boot_path = grub_util_get_path (dir, boot_file); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("The size of `%s' is not %d", + boot_path, GRUB_DISK_SECTOR_SIZE); + boot_img = grub_util_read_image (boot_path); + free (boot_path); + + /* Set the addresses of variables in the boot image. */ + boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); + root_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_ROOT_DRIVE); + kernel_sector = (grub_disk_addr_t *) (boot_img + + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + boot_drive_check = (grub_uint16_t *) (boot_img + + GRUB_BOOT_MACHINE_DRIVE_CHECK); + + core_path = grub_util_get_path (dir, core_file); + core_size = grub_util_get_image_size (core_path); + core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + if (core_size < GRUB_DISK_SECTOR_SIZE) + grub_util_error ("The size of `%s' is too small", core_path); + else if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE) + grub_util_error ("The size of `%s' is too large", core_path); + + core_img = grub_util_read_image (core_path); + + /* Have FIRST_BLOCK to point to the first blocklist. */ + first_block = (struct boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + + install_dos_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); + install_bsd_part = (grub_int32_t *) (core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART); + + /* Open the root device and the destination device. */ + root_dev = grub_device_open (root); + if (! root_dev) + grub_util_error ("%s", grub_errmsg); + + dest_dev = grub_device_open (dest); + if (! dest_dev) + grub_util_error ("%s", grub_errmsg); + + grub_util_info ("setting the root device to `%s'", root); + if (grub_env_set ("root", root) != GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); + + /* Read the original sector from the disk. */ + tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); + if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) + grub_util_error ("%s", grub_errmsg); + + /* Copy the possible DOS BPB. */ + memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, + tmp_img + GRUB_BOOT_MACHINE_BPB_START, + GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START); + + /* Copy the possible partition table. */ + if (dest_dev->disk->has_partitions) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); + + free (tmp_img); + + /* If DEST_DRIVE is a hard disk, enable the workaround, which is + for buggy BIOSes which don't pass boot drive correctly. Instead, + they pass 0x00 or 0x01 even when booted from 0x80. */ + if (dest_dev->disk->id & 0x80) + /* Replace the jmp (2 bytes) with double nop's. */ + *boot_drive_check = 0x9090; + + /* If we hardcoded drive as part of prefix, we don't want to + override the current setting. */ + if (*install_dos_part != -2) + { + /* Embed information about the installed location. */ + if (root_dev->disk->partition) + { + if (strcmp (root_dev->disk->partition->partmap->name, + "pc_partition_map") == 0) + { + struct grub_pc_partition *pcdata = + root_dev->disk->partition->data; + dos_part = pcdata->dos_part; + bsd_part = pcdata->bsd_part; + } + else if (strcmp (root_dev->disk->partition->partmap->name, + "gpt_partition_map") == 0) + { + dos_part = root_dev->disk->partition->index; + bsd_part = -1; + } + else + grub_util_error ("No PC style partitions found"); + } + else + dos_part = bsd_part = -1; + } + else + { + dos_part = grub_le_to_cpu32 (*install_dos_part); + bsd_part = grub_le_to_cpu32 (*install_bsd_part); + } + + grub_util_info ("dos partition is %d, bsd partition is %d", + dos_part, bsd_part); + + /* If the destination device can have partitions and it is the MBR, + try to embed the core image into after the MBR. */ + if (dest_dev->disk->has_partitions && ! dest_dev->disk->partition) + { + grub_partition_iterate (dest_dev->disk, find_usable_region); + + /* If there is enough space... */ + if ((unsigned long) core_sectors <= embed_region.end - embed_region.start) + { + grub_util_info ("will embed the core image at sector 0x%llx", embed_region.start); + + *install_dos_part = grub_cpu_to_le32 (dos_part); + *install_bsd_part = grub_cpu_to_le32 (bsd_part); + + /* The first blocklist contains the whole sectors. */ + first_block->start = grub_cpu_to_le64 (embed_region.start + 1); + first_block->len = grub_cpu_to_le16 (core_sectors - 1); + first_block->segment + = grub_cpu_to_le16 (GRUB_BOOT_MACHINE_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4)); + + /* Make sure that the second blocklist is a terminator. */ + block = first_block - 1; + block->start = 0; + block->len = 0; + block->segment = 0; + + /* Write the core image onto the disk. */ + if (grub_disk_write (dest_dev->disk, embed_region.start, 0, core_size, core_img)) + grub_util_error ("%s", grub_errmsg); + + /* FIXME: can this be skipped? */ + *boot_drive = 0xFF; + *root_drive = 0xFF; + + *kernel_sector = grub_cpu_to_le64 (embed_region.start); + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, + boot_img)) + grub_util_error ("%s", grub_errmsg); + + goto finish; + } + else + able_to_embed = 0; + } + else + able_to_embed = 0; + + if (must_embed && ! able_to_embed) + grub_util_error ("Core image is too big for embedding, but this is required when\n" + "the root device is on a RAID array or LVM volume."); + + /* The core image must be put on a filesystem unfortunately. */ + grub_util_info ("will leave the core image on the filesystem"); + + /* Make sure that GRUB reads the identical image as the OS. */ + tmp_img = xmalloc (core_size); + core_path_dev = grub_util_get_path (DEFAULT_DIRECTORY, core_file); + + /* It is a Good Thing to sync two times. */ + sync (); + sync (); + +#define MAX_TRIES 5 + + for (i = 0; i < MAX_TRIES; i++) + { + grub_util_info ("attempting to read the core image `%s' from GRUB%s", + core_path_dev, (i == 0) ? "" : " again"); + + grub_disk_cache_invalidate_all (); + + file = grub_file_open (core_path_dev); + if (file) + { + if (grub_file_size (file) != core_size) + grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)", + (int) grub_file_size (file), (int) core_size); + else if (grub_file_read (file, tmp_img, core_size) + != (grub_ssize_t) core_size) + grub_util_info ("succeeded in opening the core image but cannot read %d bytes", + (int) core_size); + else if (memcmp (core_img, tmp_img, core_size) != 0) + { +#if 0 + FILE *dump; + FILE *dump2; + + dump = fopen ("dump.img", "wb"); + if (dump) + { + fwrite (tmp_img, 1, core_size, dump); + fclose (dump); + } + + dump2 = fopen ("dump2.img", "wb"); + if (dump2) + { + fwrite (core_img, 1, core_size, dump2); + fclose (dump2); + } + +#endif + grub_util_info ("succeeded in opening the core image but the data is different"); + } + else + { + grub_file_close (file); + break; + } + + grub_file_close (file); + } + else + grub_util_info ("couldn't open the core image"); + + if (grub_errno) + grub_util_info ("error message = %s", grub_errmsg); + + grub_errno = GRUB_ERR_NONE; + sync (); + sleep (1); + } + + if (i == MAX_TRIES) + grub_util_error ("Cannot read `%s' correctly", core_path_dev); + + /* Clean out the blocklists. */ + block = first_block; + while (block->len) + { + block->start = 0; + block->len = 0; + block->segment = 0; + + block--; + + if ((char *) block <= core_img) + grub_util_error ("No terminator in the core image"); + } + + /* Now read the core image to determine where the sectors are. */ + file = grub_file_open (core_path_dev); + if (! file) + grub_util_error ("%s", grub_errmsg); + + file->read_hook = save_first_sector; + if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("Failed to read the first sector of the core image"); + + block = first_block; + file->read_hook = save_blocklists; + if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE) + != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) + grub_util_error ("Failed to read the rest sectors of the core image"); + + grub_file_close (file); + + free (core_path_dev); + free (tmp_img); + + *kernel_sector = grub_cpu_to_le64 (first_sector); + + /* FIXME: can this be skipped? */ + *boot_drive = 0xFF; + *root_drive = 0xFF; + + *install_dos_part = grub_cpu_to_le32 (dos_part); + *install_bsd_part = grub_cpu_to_le32 (bsd_part); + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); + fp = fopen (core_path, "r+b"); + if (! fp) + grub_util_error ("Cannot open `%s'", core_path); + + grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp); + fclose (fp); + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + finish: + + /* Sync is a Good Thing. */ + sync (); + + free (core_path); + free (core_img); + free (boot_img); + grub_device_close (dest_dev); + grub_device_close (root_dev); +} + +static struct option options[] = + { + {"boot-image", required_argument, 0, 'b'}, + {"core-image", required_argument, 0, 'c'}, + {"directory", required_argument, 0, 'd'}, + {"device-map", required_argument, 0, 'm'}, + {"root-device", required_argument, 0, 'r'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, "Try ``grub-setup --help'' for more information.\n"); + else + printf ("\ +Usage: grub-setup [OPTION]... DEVICE\n\ +\n\ +Set up images to boot from DEVICE.\n\ +DEVICE must be a GRUB device (e.g. ``(hd0,1)'').\n\ +\n\ + -b, --boot-image=FILE use FILE as the boot image [default=%s]\n\ + -c, --core-image=FILE use FILE as the core image [default=%s]\n\ + -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n\ + -m, --device-map=FILE use FILE as the device map [default=%s]\n\ + -r, --root-device=DEV use DEV as the root device [default=guessed]\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +", + DEFAULT_BOOT_FILE, DEFAULT_CORE_FILE, DEFAULT_DIRECTORY, + DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT); + + exit (status); +} + +static char * +get_device_name (char *dev) +{ + size_t len = strlen (dev); + + if (dev[0] != '(' || dev[len - 1] != ')') + return 0; + + dev[len - 1] = '\0'; + return dev + 1; +} + +int +main (int argc, char *argv[]) +{ + char *boot_file = 0; + char *core_file = 0; + char *dir = 0; + char *dev_map = 0; + char *root_dev = 0; + char *dest_dev; + int must_embed = 0; + + progname = "grub-setup"; + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "b:c:d:m:r:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'b': + if (boot_file) + free (boot_file); + + boot_file = xstrdup (optarg); + break; + + case 'c': + if (core_file) + free (core_file); + + core_file = xstrdup (optarg); + break; + + case 'd': + if (dir) + free (dir); + + dir = xstrdup (optarg); + break; + + case 'm': + if (dev_map) + free (dev_map); + + dev_map = xstrdup (optarg); + break; + + case 'r': + if (root_dev) + free (root_dev); + + root_dev = xstrdup (optarg); + break; + + case 'h': + usage (0); + break; + + case 'V': + printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + /* Obtain DEST_DEV. */ + if (optind >= argc) + { + fprintf (stderr, "No device is specified.\n"); + usage (1); + } + + if (optind + 1 != argc) + { + fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + usage (1); + } + + /* Initialize the emulated biosdisk driver. */ + grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP); + + /* Initialize all modules. */ + grub_init_all (); + + dest_dev = get_device_name (argv[optind]); + if (! dest_dev) + { + /* Possibly, the user specified an OS device file. */ + dest_dev = grub_util_get_grub_dev (argv[optind]); + if (! dest_dev) + { + fprintf (stderr, "Invalid device `%s'.\n", argv[optind]); + usage (1); + } + } + else + /* For simplicity. */ + dest_dev = xstrdup (dest_dev); + + if (root_dev) + { + char *tmp = get_device_name (root_dev); + + if (! tmp) + grub_util_error ("Invalid root device `%s'", root_dev); + + tmp = xstrdup (tmp); + free (root_dev); + root_dev = tmp; + } + else + { + root_dev = grub_util_get_grub_dev (grub_guess_root_device (dir ? : DEFAULT_DIRECTORY)); + if (! root_dev) + { + grub_util_info ("guessing the root device failed, because of `%s'", + grub_errmsg); + grub_util_error ("Cannot guess the root device. Specify the option ``--root-device''."); + } + } + +#ifdef __linux__ + if (grub_util_lvm_isvolume (root_dev)) + must_embed = 1; + + if (root_dev[0] == 'm' && root_dev[1] == 'd' + && root_dev[2] >= '0' && root_dev[2] <= '9') + { + /* FIXME: we can avoid this on RAID1. */ + must_embed = 1; + } + + if (dest_dev[0] == 'm' && dest_dev[1] == 'd' + && dest_dev[2] >= '0' && dest_dev[2] <= '9') + { + char **devicelist; + int i; + + devicelist = grub_util_raid_getmembers (dest_dev); + + for (i = 0; devicelist[i]; i++) + { + setup (dir ? : DEFAULT_DIRECTORY, + boot_file ? : DEFAULT_BOOT_FILE, + core_file ? : DEFAULT_CORE_FILE, + root_dev, grub_util_get_grub_dev (devicelist[i]), 1); + } + } + else +#endif + /* Do the real work. */ + setup (dir ? : DEFAULT_DIRECTORY, + boot_file ? : DEFAULT_BOOT_FILE, + core_file ? : DEFAULT_CORE_FILE, + root_dev, dest_dev, must_embed); + + /* Free resources. */ + grub_fini_all (); + grub_util_biosdisk_fini (); + + free (boot_file); + free (core_file); + free (dir); + free (dev_map); + free (root_dev); + free (dest_dev); + + return 0; +} diff --git a/util/i386/pc/misc.c b/util/i386/pc/misc.c new file mode 100644 index 0000000..8490fbf --- /dev/null +++ b/util/i386/pc/misc.c @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include + +void +grub_reboot (void) +{ + longjmp (main_env, 1); +} + +void +grub_halt (int no_apm __attribute__ ((unused))) +{ + grub_reboot (); +} diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in new file mode 100644 index 0000000..710ed12 --- /dev/null +++ b/util/ieee1275/grub-install.in @@ -0,0 +1,233 @@ +#! /bin/sh + +# Install GRUB on your drive. +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# This script uses `ofpathname', which is downloadable from +# http://ppc64-utils.ozlabs.org . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +sbindir=@sbindir@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ +platform=@platform@ +pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` + +grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` +grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` +rootdir= +grub_prefix=`echo /boot/grub | sed ${transform}` +modules= + +install_device= +debug=no +update_nvram=yes + +ofpathname=/usr/sbin/ofpathname +nvsetenv=/sbin/nvsetenv + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --root-directory=*) + rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; + --grub-mkdevicemap=*) + grub_mkdevicemap=`echo "$option" | sed 's/--grub-mkdevicemap=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + --grub-probe=*) + grub_probe=`echo "$option" | sed 's/--grub-probe=//'` ;; + --no-nvram) + update_nvram=no ;; + # This is an undocumented feature... + --debug) + debug=yes ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$install_device" != x; then + echo "More than one install_devices?" 1>&2 + usage + exit 1 + fi + install_device="${option}" ;; + esac +done + +# If the debugging feature is enabled, print commands. +if test $debug = yes; then + set -x +fi + +# Initialize these directories here, since ROOTDIR was initialized. +bootdir=${rootdir}/boot +grubdir=${bootdir}/`echo grub | sed ${transform}` +device_map=${grubdir}/device.map + +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + +# Find the partition at the right mount point. +install_device=`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${grubdir}` + +if test "x$install_device" = "x`$grub_mkdevicemap --device-map=/dev/stdout | $grub_probe --target=device --device-map=/dev/stdin ${bootdir}`"; then + echo "$grubdir must be a mount point." + exit 1 +fi +# XXX warn on firmware-unreadable filesystems? + +# Create the GRUB directory if it is not present. +test -d "$bootdir" || mkdir "$bootdir" || exit 1 +test -d "$grubdir" || mkdir "$grubdir" || exit 1 + +# Create the device map file if it is not present. +if test -f "$device_map"; then + : +else + # Create a safe temporary file. + test -n "$mklog" && log_file=`$mklog` + + $grub_mkdevicemap --device-map=$device_map $no_floppy || exit 1 +fi + +# Copy the GRUB images to the GRUB directory. +for file in ${grubdir}/*.mod ${grubdir}/*.lst ; do + if test -f $file; then + rm -f $file || exit 1 + fi +done +for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst ; do + cp -f $file ${grubdir} || exit 1 +done + +# Create the core image. First, auto-detect the filesystem module. +fs_module=`$grub_probe --target=fs --device-map=${device_map} ${grubdir}` +if test "x$fs_module" = x -a "x$modules" = x; then + echo "Auto-detection of a filesystem module failed." 1>&2 + echo "Please specify the module with the option \`--modules' explicitly." 1>&2 + exit 1 +fi + +# Then the partition map module. In order to support partition-less media, +# this command is allowed to fail (--target=fs already grants us that the +# filesystem will be accessible). +partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null` + +# Device abstraction module, if any (lvm, raid). +devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` + +modules="$modules $fs_module $partmap_module $devabstraction_module" + +# Now perform the installation. +"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 + +if test $update_nvram = yes; then + set $ofpathname dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + + set $nvsetenv dummy + if test -f "$1"; then + : + else + echo "$1: Not found." 1>&2 + exit 1 + fi + + # Get the Open Firmware device tree path translation. + dev=`echo $install_device | sed -e 's/\/dev\///' -e 's/[0-9]\+//'` + partno=`echo $install_device | sed -e 's/.*[^0-9]\([0-9]\+\)$/\1/'` + ofpath=`$ofpathname $dev` || { + echo "Couldn't find Open Firmware device tree path for $dev." + echo "You will have to set boot-device manually." + exit 1 + } + + # Point boot-device at the new grub install + boot_device="boot-device $ofpath:$partno,\\grub" + "$nvsetenv" "$boot_device" || { + echo "$nvsetenv failed." + echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" + echo " setenv $boot_device" + exit 1 + } +fi + +# Prompt the user to check if the device map is correct. +echo "Installation finished. No error reported." +echo "This is the contents of the device map $device_map." +echo "Check if this is correct or not. If any of the lines is incorrect," +echo "fix it and re-run the script \`grub-install'." +echo + +cat $device_map + +# Bye. +exit 0 diff --git a/util/lvm.c b/util/lvm.c new file mode 100644 index 0000000..edd31b0 --- /dev/null +++ b/util/lvm.c @@ -0,0 +1,50 @@ +/* lvm.c - LVM support for GRUB utils. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* We only support LVM on Linux. */ +#ifdef __linux__ + +#include +#include + +#include +#include + +int +grub_util_lvm_isvolume (char *name) +{ + char *devname; + struct stat st; + int err; + + devname = xmalloc (strlen (name) + 13); + + strcpy (devname, "/dev/mapper/"); + strcpy (devname+12, name); + + err = stat (devname, &st); + free (devname); + + if (err) + return 0; + else + return 1; +} + +#endif /* ! __linux__ */ diff --git a/util/misc.c b/util/misc.c new file mode 100644 index 0000000..559022f --- /dev/null +++ b/util/misc.c @@ -0,0 +1,396 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include malloc.h, only if memalign is available. It is known that + memalign is declared in malloc.h in all systems, if present. */ +#ifdef HAVE_MEMALIGN +# include +#endif + +char *progname = 0; +int verbosity = 0; + +void +grub_util_info (const char *fmt, ...) +{ + if (verbosity > 0) + { + va_list ap; + + fprintf (stderr, "%s: info: ", progname); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fputc ('\n', stderr); + fflush (stderr); + } +} + +void +grub_util_error (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, "%s: error: ", progname); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fputc ('\n', stderr); + exit (1); +} + +int +grub_err_printf (const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start (ap, fmt); + ret = vfprintf (stderr, fmt, ap); + va_end (ap); + + return ret; +} + +void * +xmalloc (size_t size) +{ + void *p; + + p = malloc (size); + if (! p) + grub_util_error ("out of memory"); + + return p; +} + +void * +xrealloc (void *ptr, size_t size) +{ + ptr = realloc (ptr, size); + if (! ptr) + grub_util_error ("out of memory"); + + return ptr; +} + +char * +xstrdup (const char *str) +{ + size_t len; + char *dup; + + len = strlen (str); + dup = (char *) xmalloc (len + 1); + memcpy (dup, str, len + 1); + + return dup; +} + +char * +grub_util_get_path (const char *dir, const char *file) +{ + char *path; + + path = (char *) xmalloc (strlen (dir) + 1 + strlen (file) + 1); + sprintf (path, "%s/%s", dir, file); + return path; +} + +size_t +grub_util_get_fp_size (FILE *fp) +{ + struct stat st; + + if (fflush (fp) == EOF) + grub_util_error ("fflush failed"); + + if (fstat (fileno (fp), &st) == -1) + grub_util_error ("fstat failed"); + + return st.st_size; +} + +size_t +grub_util_get_image_size (const char *path) +{ + struct stat st; + + grub_util_info ("getting the size of %s", path); + + if (stat (path, &st) == -1) + grub_util_error ("cannot stat %s", path); + + return st.st_size; +} + +void +grub_util_read_at (void *img, size_t size, off_t offset, FILE *fp) +{ + if (fseeko (fp, offset, SEEK_SET) == -1) + grub_util_error ("seek failed"); + + if (fread (img, 1, size, fp) != size) + grub_util_error ("read failed"); +} + +char * +grub_util_read_image (const char *path) +{ + char *img; + FILE *fp; + size_t size; + + grub_util_info ("reading %s", path); + + size = grub_util_get_image_size (path); + img = (char *) xmalloc (size); + + fp = fopen (path, "rb"); + if (! fp) + grub_util_error ("cannot open %s", path); + + grub_util_read_at (img, size, 0, fp); + + fclose (fp); + + return img; +} + +void +grub_util_load_image (const char *path, char *buf) +{ + FILE *fp; + size_t size; + + grub_util_info ("reading %s", path); + + size = grub_util_get_image_size (path); + + fp = fopen (path, "rb"); + if (! fp) + grub_util_error ("cannot open %s", path); + + if (fread (buf, 1, size, fp) != size) + grub_util_error ("cannot read %s", path); + + fclose (fp); +} + +void +grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out) +{ + grub_util_info ("writing 0x%x bytes at offset 0x%x", size, offset); + if (fseeko (out, offset, SEEK_SET) == -1) + grub_util_error ("seek failed"); + if (fwrite (img, 1, size, out) != size) + grub_util_error ("write failed"); +} + +void +grub_util_write_image (const char *img, size_t size, FILE *out) +{ + grub_util_info ("writing 0x%x bytes", size); + if (fwrite (img, 1, size, out) != size) + grub_util_error ("write failed"); +} + +void * +grub_malloc (grub_size_t size) +{ + return xmalloc (size); +} + +void +grub_free (void *ptr) +{ + free (ptr); +} + +void * +grub_realloc (void *ptr, grub_size_t size) +{ + return xrealloc (ptr, size); +} + +void * +grub_memalign (grub_size_t align, grub_size_t size) +{ + void *p; + +#if defined(HAVE_POSIX_MEMALIGN) + if (posix_memalign (&p, align, size) != 0) + p = 0; +#elif defined(HAVE_MEMALIGN) + p = memalign (align, size); +#else + (void) align; + (void) size; + grub_util_error ("grub_memalign is not supported"); +#endif + + if (! p) + grub_util_error ("out of memory"); + + return p; +} + +/* Some functions that we don't use. */ +void +grub_mm_init_region (void *addr __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + +void +grub_register_exported_symbols (void) +{ +} + +void +grub_exit (void) +{ + exit (1); +} + +grub_uint32_t +grub_get_rtc (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * GRUB_TICKS_PER_SECOND + + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec) + * GRUB_TICKS_PER_SECOND / 1000000)); +} + +grub_uint64_t +grub_get_time_ms (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} + +#ifndef HAVE_ASPRINTF + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + /* Should be large enough. */ + *buf = xmalloc (512); + + va_start (ap, fmt); + status = vsprintf (*buf, fmt, ap); + va_end (ap); + + return status; +} + +#endif + +#ifdef __MINGW32__ + +#include +#include + +void sync (void) +{ +} + +void sleep (int s) +{ + Sleep (s * 1000); +} + +grub_int64_t +grub_util_get_disk_size (char *name) +{ + HANDLE hd; + grub_int64_t size = -1LL; + + hd = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, 0, 0); + + if (hd == INVALID_HANDLE_VALUE) + return size; + + if (((name[0] == '/') || (name[0] == '\\')) && + ((name[1] == '/') || (name[1] == '\\')) && + (name[2] == '.') && + ((name[3] == '/') || (name[3] == '\\')) && + (! strncasecmp (name + 4, "PHYSICALDRIVE", 13))) + { + DWORD nr; + DISK_GEOMETRY g; + + if (! DeviceIoControl (hd, IOCTL_DISK_GET_DRIVE_GEOMETRY, + 0, 0, &g, sizeof (g), &nr, 0)) + goto fail; + + size = g.Cylinders.QuadPart; + size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector; + } + else + { + LARGE_INTEGER s; + + s.LowPart = GetFileSize (hd, &s.HighPart); + size = s.QuadPart; + } + +fail: + + CloseHandle (hd); + + return size; +} + +#endif diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in new file mode 100644 index 0000000..30bdabe --- /dev/null +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -0,0 +1,115 @@ +#! /bin/sh -e + +# Make GRUB rescue image +# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# Initialize some variables. +transform="@program_transform_name@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ +target_cpu=@target_cpu@ +platform=@platform@ +pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` + +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +input_dir=${pkglibdir} + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + --modules=*) + modules=`echo "$option" | sed 's/--modules=//'` ;; + --pkglibdir=*) + input_dir=`echo "$option" | sed 's/--pkglibdir=//'` ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + ;; + *) + if test "x$output_image" != x; then + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 1 + fi + output_image="${option}" ;; + esac +done + +if test "x$output_image" = x; then + usage + exit 1 +fi + +if [ "x${modules}" = "x" ] ; then + modules=`cd ${input_dir}/ && ls *.mod` +fi + +map_file=`mktemp` +cat >${map_file} <. + */ + +#include + +#include + +void +grub_reboot (void) +{ + longjmp (main_env, 1); +} + +void +grub_halt (void) +{ + grub_reboot (); +} diff --git a/util/raid.c b/util/raid.c new file mode 100644 index 0000000..ad6e407 --- /dev/null +++ b/util/raid.c @@ -0,0 +1,112 @@ +/* raid.c - RAID support for GRUB utils. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* We only support RAID on Linux. */ +#ifdef __linux__ +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +static char * +grub_util_getdiskname (int major, int minor) +{ + char *name = xmalloc (15); + + if (major == LOOP_MAJOR) + sprintf (name, "/dev/loop%d", minor); + else if (major == IDE0_MAJOR) + sprintf (name, "/dev/hd%c", 'a' + minor / 64); + else if (major == IDE1_MAJOR) + sprintf (name, "/dev/hd%c", 'c' + minor / 64); + else if (major == IDE2_MAJOR) + sprintf (name, "/dev/hd%c", 'e' + minor / 64); + else if (major == IDE3_MAJOR) + sprintf (name, "/dev/hd%c", 'g' + minor / 64); + else if (major == SCSI_DISK0_MAJOR) + sprintf (name, "/dev/sd%c", 'a' + minor / 16); + else + grub_util_error ("Unknown device number: %d, %d", major, minor); + + return name; +} + +char ** +grub_util_raid_getmembers (char *name) +{ + int fd, ret, i, j; + char *devname; + char **devicelist; + mdu_version_t version; + mdu_array_info_t info; + mdu_disk_info_t disk; + + devname = xmalloc (strlen (name) + 6); + strcpy (devname, "/dev/"); + strcpy (devname+5, name); + + fd = open (devname, O_RDONLY); + + if (fd == -1) + grub_util_error ("Can't open %s: %s", devname, strerror (errno)); + + free (devname); + + ret = ioctl (fd, RAID_VERSION, &version); + if (ret != 0) + grub_util_error ("ioctl RAID_VERSION error: %s", strerror (errno)); + + if (version.major != 0 || version.minor != 90) + grub_util_error ("Unsupported RAID version: %d.%d", + version.major, version.minor); + + ret = ioctl (fd, GET_ARRAY_INFO, &info); + if (ret != 0) + grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno)); + + devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); + + for (i = 0, j = 0; i . + */ + +#include +#include +#include +#include + +#include +#include + +/* Module. */ +struct mod_list +{ + const char *name; + struct mod_list *next; +}; + +/* Dependency. */ +struct dep_list +{ + const char *name; + struct mod_list *list; + struct dep_list *next; +}; + +static char buf[1024]; + +static void +free_mod_list (struct mod_list *head) +{ + while (head) + { + struct mod_list *next; + + next = head->next; + free ((void *) head->name); + free (head); + head = next; + } +} + +static void +free_dep_list (struct dep_list *head) +{ + while (head) + { + struct dep_list *next; + + next = head->next; + free ((void *) head->name); + free_mod_list (head->list); + free (head); + head = next; + } +} + +/* Read the list of dependencies. */ +static struct dep_list * +read_dep_list (FILE *fp) +{ + struct dep_list *dep_list = 0; + + while (fgets (buf, sizeof (buf), fp)) + { + char *p; + struct dep_list *dep; + + /* Get the target name. */ + p = strchr (buf, ':'); + if (! p) + grub_util_error ("invalid line format: %s", buf); + + *p++ = '\0'; + + dep = xmalloc (sizeof (*dep)); + dep->name = xstrdup (buf); + dep->list = 0; + + dep->next = dep_list; + dep_list = dep; + + /* Add dependencies. */ + while (*p) + { + struct mod_list *mod; + char *name; + + /* Skip white spaces. */ + while (*p && isspace (*p)) + p++; + + if (! *p) + break; + + name = p; + + /* Skip non-WSPs. */ + while (*p && ! isspace (*p)) + p++; + + *p++ = '\0'; + + mod = (struct mod_list *) xmalloc (sizeof (*mod)); + mod->name = xstrdup (name); + mod->next = dep->list; + dep->list = mod; + } + } + + return dep_list; +} + +static char * +get_module_name (const char *str) +{ + char *base; + char *ext; + + base = strrchr (str, '/'); + if (! base) + base = (char *) str; + else + base++; + + ext = strrchr (base, '.'); + if (ext && strcmp (ext, ".mod") == 0) + { + char *name; + + name = xmalloc (ext - base + 1); + memcpy (name, base, ext - base); + name[ext - base] = '\0'; + return name; + } + + return xstrdup (base); +} + +static char * +get_module_path (const char *prefix, const char *str) +{ + char *dir; + char *base; + char *ext; + char *ret; + + ext = strrchr (str, '.'); + if (ext && strcmp (ext, ".mod") == 0) + base = xstrdup (str); + else + { + base = xmalloc (strlen (str) + 4 + 1); + sprintf (base, "%s.mod", str); + } + + dir = strchr (str, '/'); + if (dir) + return base; + + ret = grub_util_get_path (prefix, base); + free (base); + return ret; +} + +static void +add_module (const char *dir, + struct dep_list *dep_list, + struct mod_list **mod_head, + struct grub_util_path_list **path_head, + const char *name) +{ + char *mod_name; + struct grub_util_path_list *path; + struct mod_list *mod; + struct dep_list *dep; + + mod_name = get_module_name (name); + + /* Check if the module has already been added. */ + for (mod = *mod_head; mod; mod = mod->next) + if (strcmp (mod->name, mod_name) == 0) + { + free (mod_name); + return; + } + + /* Resolve dependencies. */ + for (dep = dep_list; dep; dep = dep->next) + if (strcmp (dep->name, mod_name) == 0) + { + for (mod = dep->list; mod; mod = mod->next) + add_module (dir, dep_list, mod_head, path_head, mod->name); + + break; + } + + /* Add this module. */ + mod = (struct mod_list *) xmalloc (sizeof (*mod)); + mod->name = mod_name; + mod->next = *mod_head; + *mod_head = mod; + + /* Add this path. */ + path = (struct grub_util_path_list *) xmalloc (sizeof (*path)); + path->name = get_module_path (dir, name); + path->next = *path_head; + *path_head = path; +} + +struct grub_util_path_list * +grub_util_resolve_dependencies (const char *prefix, + const char *dep_list_file, + char *modules[]) +{ + char *path; + FILE *fp; + struct dep_list *dep_list; + struct mod_list *mod_list = 0; + struct grub_util_path_list *path_list = 0; + + path = grub_util_get_path (prefix, dep_list_file); + fp = fopen (path, "r"); + if (! fp) + grub_util_error ("cannot open %s", path); + + free (path); + dep_list = read_dep_list (fp); + fclose (fp); + + while (*modules) + { + add_module (prefix, dep_list, &mod_list, &path_list, *modules); + modules++; + } + + free_dep_list (dep_list); + free_mod_list (mod_list); + + { /* Reverse the path_list */ + struct grub_util_path_list *p, *prev, *next; + + for (p = path_list, prev = NULL; p; p = next) + { + next = p->next; + p->next = prev; + prev = p; + } + + return prev; + } +} diff --git a/util/update-grub_lib.in b/util/update-grub_lib.in new file mode 100644 index 0000000..998452e --- /dev/null +++ b/util/update-grub_lib.in @@ -0,0 +1,23 @@ +# stub for new grub-mkconfig_lib +# Copyright (C) 2007,2008 Free Software Foundation, Inc. +# +# GRUB 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, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ + +. ${libdir}/grub/grub-mkconfig_lib + +grub_warn "update-grub_lib is deprecated, use grub-mkconfig_lib instead" diff --git a/util/usb.c b/util/usb.c new file mode 100644 index 0000000..744ad86 --- /dev/null +++ b/util/usb.c @@ -0,0 +1,191 @@ +/* usb.c -- libusb USB support for GRUB. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + + +static struct grub_usb_controller_dev usb_controller = +{ + .name = "libusb" +}; + +static struct grub_usb_device *grub_usb_devs[128]; + +struct usb_bus *busses; + +static grub_err_t +grub_libusb_devices (void) + +{ + struct usb_bus *bus; + int last = 0; + + busses = usb_get_busses(); + + for (bus = busses; bus; bus = bus->next) + { + struct usb_device *usbdev; + struct grub_usb_device *dev; + + for (usbdev = bus->devices; usbdev; usbdev = usbdev->next) + { + struct usb_device_descriptor *desc = &usbdev->descriptor; + + if (! desc->bcdUSB) + continue; + + dev = grub_malloc (sizeof (*dev)); + if (! dev) + return grub_errno; + + dev->data = usbdev; + + /* Fill in all descriptors. */ + grub_usb_device_initialize (dev); + + /* Register the device. */ + grub_usb_devs[last++] = dev; + } + } + + return GRUB_USB_ERR_NONE; +} + +grub_err_t +grub_libusb_init (void) +{ + usb_init(); + usb_find_busses(); + usb_find_devices(); + + if (grub_libusb_devices ()) + return grub_errno; + + grub_usb_controller_dev_register (&usb_controller); + + return 0; +} + +grub_err_t +grub_libusb_fini (void) +{ + return 0; +} + + +int +grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) +{ + int i; + + for (i = 0; i < 128; i++) + { + if (grub_usb_devs[i]) + { + if (hook (grub_usb_devs[i])) + return 1; + } + } + + return 0; +} + +grub_usb_err_t +grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused))) +{ + return GRUB_USB_ERR_NONE; +} + +grub_usb_err_t +grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, + grub_uint8_t request, grub_uint16_t value, + grub_uint16_t index, grub_size_t size, char *data) +{ + usb_dev_handle *devh; + struct usb_device *d = dev->data; + + devh = usb_open (d); + if (usb_control_msg (devh, reqtype, request, + value, index, data, size, 20) < 0) + { + usb_close (devh); + return GRUB_USB_ERR_STALL; + } + + usb_close (devh); + + return GRUB_USB_ERR_NONE; +} + +grub_usb_err_t +grub_usb_bulk_read (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data) +{ + usb_dev_handle *devh; + struct usb_device *d = dev->data; + + devh = usb_open (d); + if (usb_claim_interface (devh, 0) < 1) + { + usb_close (devh); + return GRUB_USB_ERR_STALL; + } + + if (usb_bulk_read (devh, endpoint, data, size, 20) < 1) + { + usb_close (devh); + return GRUB_USB_ERR_STALL; + } + + usb_release_interface (devh, 0); + usb_close (devh); + + return GRUB_USB_ERR_NONE; +} + +grub_usb_err_t +grub_usb_bulk_write (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data) +{ + usb_dev_handle *devh; + struct usb_device *d = dev->data; + + devh = usb_open (d); + if (usb_claim_interface (devh, 0) < 0) + goto fail; + + if (usb_bulk_write (devh, endpoint, data, size, 20) < 0) + goto fail; + + if (usb_release_interface (devh, 0) < 0) + goto fail; + + usb_close (devh); + + return GRUB_USB_ERR_NONE; + + fail: + usb_close (devh); + return GRUB_USB_ERR_STALL; +} diff --git a/video/bitmap.c b/video/bitmap.c new file mode 100644 index 0000000..8fda511 --- /dev/null +++ b/video/bitmap.c @@ -0,0 +1,256 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* List of bitmap readers registered to system. */ +static grub_video_bitmap_reader_t bitmap_readers_list; + +/* Register bitmap reader. */ +void +grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader) +{ + reader->next = bitmap_readers_list; + bitmap_readers_list = reader; +} + +/* Unregister bitmap reader. */ +void +grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader) +{ + grub_video_bitmap_reader_t *p, q; + + for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next) + if (q == reader) + { + *p = q->next; + break; + } +} + +/* Creates new bitmap, saves created bitmap on success to *bitmap. */ +grub_err_t +grub_video_bitmap_create (struct grub_video_bitmap **bitmap, + unsigned int width, unsigned int height, + enum grub_video_blit_format blit_format) +{ + struct grub_video_mode_info *mode_info; + unsigned int size; + + if (!bitmap) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + + *bitmap = 0; + + if (width == 0 || height == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + + *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap)); + if (! *bitmap) + return grub_errno; + + mode_info = &((*bitmap)->mode_info); + + /* Populate mode_info. */ + mode_info->width = width; + mode_info->height = height; + mode_info->blit_format = blit_format; + + switch (blit_format) + { + case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888: + mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA; + mode_info->bpp = 32; + mode_info->bytes_per_pixel = 4; + mode_info->number_of_colors = 256; + mode_info->red_mask_size = 8; + mode_info->red_field_pos = 0; + mode_info->green_mask_size = 8; + mode_info->green_field_pos = 8; + mode_info->blue_mask_size = 8; + mode_info->blue_field_pos = 16; + mode_info->reserved_mask_size = 8; + mode_info->reserved_field_pos = 24; + break; + + case GRUB_VIDEO_BLIT_FORMAT_RGB_888: + mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + mode_info->bpp = 24; + mode_info->bytes_per_pixel = 3; + mode_info->number_of_colors = 256; + mode_info->red_mask_size = 8; + mode_info->red_field_pos = 0; + mode_info->green_mask_size = 8; + mode_info->green_field_pos = 8; + mode_info->blue_mask_size = 8; + mode_info->blue_field_pos = 16; + mode_info->reserved_mask_size = 0; + mode_info->reserved_field_pos = 0; + break; + + case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR: + mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + mode_info->bpp = 8; + mode_info->bytes_per_pixel = 1; + mode_info->number_of_colors = 256; + mode_info->red_mask_size = 0; + mode_info->red_field_pos = 0; + mode_info->green_mask_size = 0; + mode_info->green_field_pos = 0; + mode_info->blue_mask_size = 0; + mode_info->blue_field_pos = 0; + mode_info->reserved_mask_size = 0; + mode_info->reserved_field_pos = 0; + break; + + default: + grub_free (*bitmap); + *bitmap = 0; + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported bitmap format"); + } + + mode_info->pitch = width * mode_info->bytes_per_pixel; + + /* Calculate size needed for the data. */ + size = (width * mode_info->bytes_per_pixel) * height; + + (*bitmap)->data = grub_malloc (size); + if (! (*bitmap)->data) + { + grub_free (*bitmap); + *bitmap = 0; + + return grub_errno; + } + + /* Clear bitmap. */ + grub_memset ((*bitmap)->data, 0, size); + + return GRUB_ERR_NONE; +} + +/* Frees all resources allocated by bitmap. */ +grub_err_t +grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap) +{ + if (! bitmap) + return GRUB_ERR_NONE; + + grub_free (bitmap->data); + grub_free (bitmap); + + return GRUB_ERR_NONE; +} + +/* Match extension to filename. */ +static int +match_extension (const char *filename, const char *ext) +{ + int pos; + int ext_len; + + pos = grub_strlen (filename); + ext_len = grub_strlen (ext); + + if (! pos || ! ext_len || ext_len > pos) + return 0; + + pos -= ext_len; + + return grub_strcmp (filename + pos, ext) == 0; +} + +/* Loads bitmap using registered bitmap readers. */ +grub_err_t +grub_video_bitmap_load (struct grub_video_bitmap **bitmap, + const char *filename) +{ + grub_video_bitmap_reader_t reader = bitmap_readers_list; + + if (!bitmap) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + + *bitmap = 0; + + while (reader) + { + if (match_extension (filename, reader->extension)) + return reader->reader (bitmap, filename); + + reader = reader->next; + } + + return grub_error(GRUB_ERR_BAD_FILE_TYPE, "unsupported bitmap format"); +} + +/* Return bitmap width. */ +unsigned int +grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap) +{ + if (!bitmap) + return 0; + + return bitmap->mode_info.width; +} + +/* Return bitmap height. */ +unsigned int +grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) +{ + if (!bitmap) + return 0; + + return bitmap->mode_info.height; +} + +/* Return mode info for bitmap. */ +void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, + struct grub_video_mode_info *mode_info) +{ + if (!bitmap) + return; + + *mode_info = bitmap->mode_info; +} + +/* Return pointer to bitmap's raw data. */ +void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap) +{ + if (!bitmap) + return 0; + + return bitmap->data; +} + +/* Initialize bitmap module. */ +GRUB_MOD_INIT(video_bitmap) +{ +} + +/* Finalize bitmap module. */ +GRUB_MOD_FINI(video_bitmap) +{ +} diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c new file mode 100644 index 0000000..23f7d46 --- /dev/null +++ b/video/i386/pc/vbe.c @@ -0,0 +1,1635 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Specify "standard" VGA palette, some video cards may + need this and this will also be used when using RGB modes. */ +static struct grub_vbe_palette_data vga_colors[16] = + { + // {B, G, R, A} + {0x00, 0x00, 0x00, 0x00}, // 0 = black + {0xA8, 0x00, 0x00, 0x00}, // 1 = blue + {0x00, 0xA8, 0x00, 0x00}, // 2 = green + {0xA8, 0xA8, 0x00, 0x00}, // 3 = cyan + {0x00, 0x00, 0xA8, 0x00}, // 4 = red + {0xA8, 0x00, 0xA8, 0x00}, // 5 = magenta + {0x00, 0x54, 0xA8, 0x00}, // 6 = brown + {0xA8, 0xA8, 0xA8, 0x00}, // 7 = ligth gray + + {0x54, 0x54, 0x54, 0x00}, // 8 = dark gray + {0xFE, 0x54, 0x54, 0x00}, // 9 = bright blue + {0x54, 0xFE, 0x54, 0x00}, // 10 = bright green + {0xFE, 0xFE, 0x54, 0x00}, // 11 = bright cyan + {0x54, 0x54, 0xFE, 0x00}, // 12 = bright red + {0xFE, 0x54, 0xFE, 0x00}, // 13 = bright magenta + {0x54, 0xFE, 0xFE, 0x00}, // 14 = yellow + {0xFE, 0xFE, 0xFE, 0x00} // 15 = white + }; + +static int vbe_detected = -1; + +static struct grub_vbe_info_block controller_info; +static struct grub_vbe_mode_info_block active_mode_info; + +static struct +{ + struct grub_video_render_target render_target; + + unsigned int bytes_per_scan_line; + unsigned int bytes_per_pixel; + grub_uint32_t active_mode; + grub_uint8_t *ptr; + int index_color_mode; + struct grub_video_palette_data palette[256]; +} framebuffer; + +static struct grub_video_render_target *render_target; +static grub_uint32_t initial_mode; +static grub_uint32_t mode_in_use = 0x55aa; +static grub_uint16_t *mode_list; + +static void * +real2pm (grub_vbe_farptr_t ptr) +{ + return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL) + + ((unsigned long) ptr & 0x0000FFFF)); +} + +grub_err_t +grub_vbe_probe (struct grub_vbe_info_block *info_block) +{ + struct grub_vbe_info_block *vbe_ib; + grub_vbe_status_t status; + + /* Clear caller's controller info block. */ + if (info_block) + grub_memset (info_block, 0, sizeof (*info_block)); + + /* Do not probe more than one time, if not necessary. */ + if (vbe_detected == -1 || info_block) + { + /* Clear old copy of controller info block. */ + grub_memset (&controller_info, 0, sizeof (controller_info)); + + /* Mark VESA BIOS extension as undetected. */ + vbe_detected = 0; + + /* Use low memory scratch area as temporary storage + for VESA BIOS call. */ + vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Prepare info block. */ + grub_memset (vbe_ib, 0, sizeof (*vbe_ib)); + + vbe_ib->signature[0] = 'V'; + vbe_ib->signature[1] = 'B'; + vbe_ib->signature[2] = 'E'; + vbe_ib->signature[3] = '2'; + + /* Try to get controller info block. */ + status = grub_vbe_bios_get_controller_info (vbe_ib); + if (status == 0x004F) + { + /* Copy it for later usage. */ + grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info)); + + /* Mark VESA BIOS extension as detected. */ + vbe_detected = 1; + } + } + + if (! vbe_detected) + return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found"); + + /* Make copy of controller info block to caller. */ + if (info_block) + grub_memcpy (info_block, &controller_info, sizeof (*info_block)); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_vbe_set_video_mode (grub_uint32_t mode, + struct grub_vbe_mode_info_block *mode_info) +{ + grub_vbe_status_t status; + grub_uint32_t old_mode; + + /* Make sure that VBE is supported. */ + grub_vbe_probe (0); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Try to get mode info. */ + grub_vbe_get_video_mode_info (mode, &active_mode_info); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* For all VESA BIOS modes, force linear frame buffer. */ + if (mode >= 0x100) + { + /* We only want linear frame buffer modes. */ + mode |= 1 << 14; + + /* Determine frame buffer pixel format. */ + switch (active_mode_info.memory_model) + { + case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL: + framebuffer.index_color_mode = 1; + break; + + case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR: + framebuffer.index_color_mode = 0; + break; + + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "unsupported pixel format 0x%x", + active_mode_info.memory_model); + } + } + + /* Get current mode. */ + grub_vbe_get_video_mode (&old_mode); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Try to set video mode. */ + status = grub_vbe_bios_set_mode (mode, 0); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", mode); + + /* Save information for later usage. */ + framebuffer.active_mode = mode; + + if (mode < 0x100) + { + /* If this is not a VESA mode, guess address. */ + framebuffer.ptr = (grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR; + framebuffer.index_color_mode = 1; + } + else + { + framebuffer.ptr = (grub_uint8_t *) active_mode_info.phys_base_addr; + + if (controller_info.version >= 0x300) + framebuffer.bytes_per_scan_line = active_mode_info.lin_bytes_per_scan_line; + else + framebuffer.bytes_per_scan_line = active_mode_info.bytes_per_scan_line; + } + + /* Check whether mode is text mode or graphics mode. */ + if (active_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + { + /* Text mode. */ + + /* No special action needed for text mode as it is not supported for + graphical support. */ + } + else + { + /* Graphics mode. */ + + /* Calculate bytes_per_pixel value. */ + switch(active_mode_info.bits_per_pixel) + { + case 32: framebuffer.bytes_per_pixel = 4; break; + case 24: framebuffer.bytes_per_pixel = 3; break; + case 16: framebuffer.bytes_per_pixel = 2; break; + case 15: framebuffer.bytes_per_pixel = 2; break; + case 8: framebuffer.bytes_per_pixel = 1; break; + default: + grub_vbe_bios_set_mode (old_mode, 0); + return grub_error (GRUB_ERR_BAD_DEVICE, + "cannot set VBE mode %x", + mode); + break; + } + + /* If video mode is in indexed color, setup default VGA palette. */ + if (framebuffer.index_color_mode) + { + struct grub_vbe_palette_data *palette + = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + /* Make sure that the BIOS can reach the palette. */ + grub_memcpy (palette, vga_colors, sizeof (vga_colors)); + status = grub_vbe_bios_set_palette_data (sizeof (vga_colors) + / sizeof (struct grub_vbe_palette_data), + 0, + palette); + + /* Just ignore the status. */ + } + } + + /* Copy mode info for caller. */ + if (mode_info) + grub_memcpy (mode_info, &active_mode_info, sizeof (*mode_info)); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_vbe_get_video_mode (grub_uint32_t *mode) +{ + grub_vbe_status_t status; + + /* Make sure that VBE is supported. */ + grub_vbe_probe (0); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Try to query current mode from VESA BIOS. */ + status = grub_vbe_bios_get_mode (mode); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_vbe_get_video_mode_info (grub_uint32_t mode, + struct grub_vbe_mode_info_block *mode_info) +{ + struct grub_vbe_mode_info_block *mi_tmp + = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_vbe_status_t status; + + /* Make sure that VBE is supported. */ + grub_vbe_probe (0); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* If mode is not VESA mode, skip mode info query. */ + if (mode >= 0x100) + { + /* Try to get mode info from VESA BIOS. */ + status = grub_vbe_bios_get_mode_info (mode, mi_tmp); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get information on the mode %x", mode); + + /* Make copy of mode info block. */ + grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info)); + } + else + /* Just clear mode info block if it isn't a VESA mode. */ + grub_memset (mode_info, 0, sizeof (*mode_info)); + + return GRUB_ERR_NONE; +} + +grub_uint8_t * +grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source, + grub_uint32_t x, grub_uint32_t y) +{ + grub_uint8_t *ptr = 0; + + switch (source->mode_info->bpp) + { + case 32: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 4; + break; + + case 24: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 3; + break; + + case 16: + case 15: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 2; + break; + + case 8: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x; + break; + } + + return ptr; +} + +static grub_err_t +grub_video_vbe_init (void) +{ + grub_uint16_t *rm_mode_list; + grub_uint16_t *p; + grub_size_t mode_list_size; + struct grub_vbe_info_block info_block; + + /* Check if there is adapter present. + + Firmware note: There has been a report that some cards store video mode + list in temporary memory. So we must first use vbe probe to get + refreshed information to receive valid pointers and data, and then + copy this information to somewhere safe. */ + grub_vbe_probe (&info_block); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Copy modelist to local memory. */ + p = rm_mode_list = real2pm (info_block.video_mode_ptr); + while(*p++ != 0xFFFF) + ; + + mode_list_size = (grub_addr_t) p - (grub_addr_t) rm_mode_list; + mode_list = grub_malloc (mode_list_size); + if (! mode_list) + return grub_errno; + grub_memcpy (mode_list, rm_mode_list, mode_list_size); + + /* Adapter could be found, figure out initial video mode. */ + grub_vbe_get_video_mode (&initial_mode); + if (grub_errno != GRUB_ERR_NONE) + { + /* Free allocated resources. */ + grub_free (mode_list); + mode_list = 0; + + return grub_errno; + } + + /* Reset frame buffer and render target variables. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + render_target = &framebuffer.render_target; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_fini (void) +{ + grub_vbe_status_t status; + + /* Restore old video mode. */ + status = grub_vbe_bios_set_mode (initial_mode, 0); + if (status != GRUB_VBE_STATUS_OK) + /* TODO: Decide, is this something we want to do. */ + return grub_errno; + + /* TODO: Free any resources allocated by driver. */ + grub_free (mode_list); + mode_list = 0; + + /* TODO: destroy render targets. */ + + /* Return success to caller. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_setup (unsigned int width, unsigned int height, + unsigned int mode_type) +{ + grub_uint16_t *p; + struct grub_vbe_mode_info_block mode_info; + struct grub_vbe_mode_info_block best_mode_info; + grub_uint32_t best_mode = 0; + int depth; + unsigned int i; + + /* Decode depth from mode_type. If it is zero, then autodetect. */ + depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; + + /* Walk thru mode list and try to find matching mode. */ + for (p = mode_list; *p != 0xFFFF; p++) + { + grub_uint32_t mode = *p; + + grub_vbe_get_video_mode_info (mode, &mode_info); + if (grub_errno != GRUB_ERR_NONE) + { + /* Could not retrieve mode info, retreat. */ + grub_errno = GRUB_ERR_NONE; + break; + } + + if ((mode_info.mode_attributes & 0x001) == 0) + /* If not available, skip it. */ + continue; + + if ((mode_info.mode_attributes & 0x002) == 0) + /* Not enough information. */ + continue; + + if ((mode_info.mode_attributes & 0x008) == 0) + /* Monochrome is unusable. */ + continue; + + if ((mode_info.mode_attributes & 0x080) == 0) + /* We support only linear frame buffer modes. */ + continue; + + if ((mode_info.mode_attributes & 0x010) == 0) + /* We allow only graphical modes. */ + continue; + + if ((mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL) + && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) + /* Not compatible memory model. */ + continue; + + if ((mode_info.x_resolution != width) + || (mode_info.y_resolution != height)) + /* Non matching resolution. */ + continue; + + /* Check if user requested RGB or index color mode. */ + if ((mode_type & GRUB_VIDEO_MODE_TYPE_COLOR_MASK) != 0) + { + if (((mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) + && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)) + /* Requested only index color modes. */ + continue; + + if (((mode_type & GRUB_VIDEO_MODE_TYPE_RGB) != 0) + && (mode_info.memory_model != GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)) + /* Requested only RGB modes. */ + continue; + } + + /* If there is a request for specific depth, ignore others. */ + if ((depth != 0) && (mode_info.bits_per_pixel != depth)) + continue; + + /* Select mode with most number of bits per pixel. */ + if (best_mode != 0) + if (mode_info.bits_per_pixel < best_mode_info.bits_per_pixel) + continue; + + /* Save so far best mode information for later use. */ + best_mode = mode; + grub_memcpy (&best_mode_info, &mode_info, sizeof (mode_info)); + } + + /* Try to initialize best mode found. */ + if (best_mode != 0) + { + /* If this fails, then we have mode selection heuristics problem, + or adapter failure. */ + grub_vbe_set_video_mode (best_mode, &active_mode_info); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Now we are happily in requested video mode. Cache some info + in order to fasten later operations. */ + mode_in_use = best_mode; + + /* Reset render target to framebuffer one. */ + render_target = &framebuffer.render_target; + + /* Fill mode info details in framebuffer's render target. */ + render_target->mode_info.width = active_mode_info.x_resolution; + render_target->mode_info.height = active_mode_info.y_resolution; + + if (framebuffer.index_color_mode) + render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + else + render_target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + + render_target->mode_info.bpp = active_mode_info.bits_per_pixel; + render_target->mode_info.bytes_per_pixel = framebuffer.bytes_per_pixel; + render_target->mode_info.pitch = framebuffer.bytes_per_scan_line; + render_target->mode_info.number_of_colors = 256; /* TODO: fix me. */ + render_target->mode_info.red_mask_size = active_mode_info.red_mask_size; + render_target->mode_info.red_field_pos = active_mode_info.red_field_position; + render_target->mode_info.green_mask_size = active_mode_info.green_mask_size; + render_target->mode_info.green_field_pos = active_mode_info.green_field_position; + render_target->mode_info.blue_mask_size = active_mode_info.blue_mask_size; + render_target->mode_info.blue_field_pos = active_mode_info.blue_field_position; + render_target->mode_info.reserved_mask_size = active_mode_info.rsvd_mask_size; + render_target->mode_info.reserved_field_pos = active_mode_info.rsvd_field_position; + + render_target->mode_info.blit_format = grub_video_get_blit_format (&render_target->mode_info); + + /* Reset viewport to match new mode. */ + render_target->viewport.x = 0; + render_target->viewport.y = 0; + render_target->viewport.width = active_mode_info.x_resolution; + render_target->viewport.height = active_mode_info.y_resolution; + + /* Set framebuffer pointer and mark it as non allocated. */ + render_target->is_allocated = 0; + render_target->data = framebuffer.ptr; + + /* Copy default palette to initialize emulated palette. */ + for (i = 0; + i < (sizeof (vga_colors) + / sizeof (struct grub_vbe_palette_data)); + i++) + { + framebuffer.palette[i].r = vga_colors[i].red; + framebuffer.palette[i].g = vga_colors[i].green; + framebuffer.palette[i].b = vga_colors[i].blue; + framebuffer.palette[i].a = 0xFF; + } + + return GRUB_ERR_NONE; + } + + /* Couldn't found matching mode. */ + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found."); +} + +static grub_err_t +grub_video_vbe_get_info (struct grub_video_mode_info *mode_info) +{ + /* Copy mode info from active render target. */ + grub_memcpy (mode_info, &render_target->mode_info, + sizeof (struct grub_video_mode_info)); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + unsigned int i; + + if (framebuffer.index_color_mode) + { + /* TODO: Implement setting indexed color mode palette to hardware. */ + //status = grub_vbe_bios_set_palette_data (sizeof (vga_colors) + // / sizeof (struct grub_vbe_palette_data), + // 0, + // palette); + + } + + /* Then set color to emulated palette. */ + for (i = 0; (i < count) && ((i + start) < 256); i++) + framebuffer.palette[start + i] = palette_data[i]; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_get_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + unsigned int i; + + /* Assume that we know everything from index color palette. */ + for (i = 0; (i < count) && ((i + start) < 256); i++) + palette_data[i] = framebuffer.palette[start + i]; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_set_viewport (unsigned int x, unsigned int y, + unsigned int width, unsigned int height) +{ + /* Make sure viewport is withing screen dimensions. If viewport was set + to be out of the region, mark its size as zero. */ + if (x > active_mode_info.x_resolution) + { + x = 0; + width = 0; + } + + if (y > active_mode_info.y_resolution) + { + y = 0; + height = 0; + } + + if (x + width > active_mode_info.x_resolution) + width = active_mode_info.x_resolution - x; + + if (y + height > active_mode_info.y_resolution) + height = active_mode_info.y_resolution - y; + + render_target->viewport.x = x; + render_target->viewport.y = y; + render_target->viewport.width = width; + render_target->viewport.height = height; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_get_viewport (unsigned int *x, unsigned int *y, + unsigned int *width, unsigned int *height) +{ + if (x) *x = render_target->viewport.x; + if (y) *y = render_target->viewport.y; + if (width) *width = render_target->viewport.width; + if (height) *height = render_target->viewport.height; + + return GRUB_ERR_NONE; +} + +/* Maps color name to target optimized color format. */ +static grub_video_color_t +grub_video_vbe_map_color (grub_uint32_t color_name) +{ + /* TODO: implement color theme mapping code. */ + + if (color_name < 256) + { + if ((render_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) + return color_name; + else + { + grub_video_color_t color; + + color = grub_video_vbe_map_rgb (framebuffer.palette[color_name].r, + framebuffer.palette[color_name].g, + framebuffer.palette[color_name].b); + + return color; + } + } + + return 0; +} + +/* Maps RGB to target optimized color format. */ +grub_video_color_t +grub_video_vbe_map_rgb (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue) +{ + if ((render_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) + { + int minindex = 0; + int delta = 0; + int tmp; + int val; + int i; + + /* Find best matching color. */ + for (i = 0; i < 256; i++) + { + val = framebuffer.palette[i].r - red; + tmp = val * val; + val = framebuffer.palette[i].g - green; + tmp += val * val; + val = framebuffer.palette[i].b - blue; + tmp += val * val; + + if (i == 0) + delta = tmp; + + if (tmp < delta) + { + delta = tmp; + minindex = i; + if (tmp == 0) + break; + } + } + + return minindex; + } + else if ((render_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) + { + if (red == render_target->mode_info.fg_red + && green == render_target->mode_info.fg_green + && blue == render_target->mode_info.fg_blue) + return 1; + else + return 0; + } + else + { + grub_uint32_t value; + grub_uint8_t alpha = 255; /* Opaque color. */ + + red >>= 8 - render_target->mode_info.red_mask_size; + green >>= 8 - render_target->mode_info.green_mask_size; + blue >>= 8 - render_target->mode_info.blue_mask_size; + alpha >>= 8 - render_target->mode_info.reserved_mask_size; + + value = red << render_target->mode_info.red_field_pos; + value |= green << render_target->mode_info.green_field_pos; + value |= blue << render_target->mode_info.blue_field_pos; + value |= alpha << render_target->mode_info.reserved_field_pos; + + return value; + } + +} + +/* Maps RGBA to target optimized color format. */ +grub_video_color_t +grub_video_vbe_map_rgba (grub_uint8_t red, grub_uint8_t green, + grub_uint8_t blue, grub_uint8_t alpha) +{ + if ((render_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) + /* No alpha available in index color modes, just use + same value as in only RGB modes. */ + return grub_video_vbe_map_rgb (red, green, blue); + else if ((render_target->mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) + { + if (red == render_target->mode_info.fg_red + && green == render_target->mode_info.fg_green + && blue == render_target->mode_info.fg_blue + && alpha == render_target->mode_info.fg_alpha) + return 1; + else + return 0; + } + else + { + grub_uint32_t value; + + red >>= 8 - render_target->mode_info.red_mask_size; + green >>= 8 - render_target->mode_info.green_mask_size; + blue >>= 8 - render_target->mode_info.blue_mask_size; + alpha >>= 8 - render_target->mode_info.reserved_mask_size; + + value = red << render_target->mode_info.red_field_pos; + value |= green << render_target->mode_info.green_field_pos; + value |= blue << render_target->mode_info.blue_field_pos; + value |= alpha << render_target->mode_info.reserved_field_pos; + + return value; + } +} + +/* Splits target optimized format to components. */ +grub_err_t grub_video_vbe_unmap_color (grub_video_color_t color, + grub_uint8_t *red, grub_uint8_t *green, + grub_uint8_t *blue, grub_uint8_t *alpha) +{ + struct grub_video_i386_vbeblit_info target_info; + + target_info.mode_info = &render_target->mode_info; + target_info.data = render_target->data; + + grub_video_vbe_unmap_color_int (&target_info, color, red, green, blue, alpha); + + return GRUB_ERR_NONE; +} + +/* Splits color in source format to components. */ +void +grub_video_vbe_unmap_color_int (struct grub_video_i386_vbeblit_info * source, + grub_video_color_t color, + grub_uint8_t *red, grub_uint8_t *green, + grub_uint8_t *blue, grub_uint8_t *alpha) +{ + struct grub_video_mode_info *mode_info; + mode_info = source->mode_info; + + if ((mode_info->mode_type + & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != 0) + { + /* If we have an out-of-bounds color, return transparent black. */ + if (color > 255) + { + *red = 0; + *green = 0; + *blue = 0; + *alpha = 0; + return; + } + + *red = framebuffer.palette[color].r; + *green = framebuffer.palette[color].g; + *blue = framebuffer.palette[color].b; + *alpha = framebuffer.palette[color].a; + return; + } + else if ((mode_info->mode_type + & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0) + { + if (color & 1) + { + *red = mode_info->fg_red; + *green = mode_info->fg_green; + *blue = mode_info->fg_blue; + *alpha = mode_info->fg_alpha; + } + else + { + *red = mode_info->bg_red; + *green = mode_info->bg_green; + *blue = mode_info->bg_blue; + *alpha = mode_info->bg_alpha; + } + } + else + { + grub_uint32_t tmp; + + /* Get red component. */ + tmp = color >> mode_info->red_field_pos; + tmp &= (1 << mode_info->red_mask_size) - 1; + tmp <<= 8 - mode_info->red_mask_size; + tmp |= (1 << (8 - mode_info->red_mask_size)) - 1; + *red = tmp & 0xFF; + + /* Get green component. */ + tmp = color >> mode_info->green_field_pos; + tmp &= (1 << mode_info->green_mask_size) - 1; + tmp <<= 8 - mode_info->green_mask_size; + tmp |= (1 << (8 - mode_info->green_mask_size)) - 1; + *green = tmp & 0xFF; + + /* Get blue component. */ + tmp = color >> mode_info->blue_field_pos; + tmp &= (1 << mode_info->blue_mask_size) - 1; + tmp <<= 8 - mode_info->blue_mask_size; + tmp |= (1 << (8 - mode_info->blue_mask_size)) - 1; + *blue = tmp & 0xFF; + + /* Get alpha component. */ + if (source->mode_info->reserved_mask_size > 0) + { + tmp = color >> mode_info->reserved_field_pos; + tmp &= (1 << mode_info->reserved_mask_size) - 1; + tmp <<= 8 - mode_info->reserved_mask_size; + tmp |= (1 << (8 - mode_info->reserved_mask_size)) - 1; + } + else + /* If there is no alpha component, assume it opaque. */ + tmp = 255; + + *alpha = tmp & 0xFF; + } +} + +static grub_err_t +grub_video_vbe_fill_rect (grub_video_color_t color, int x, int y, + unsigned int width, unsigned int height) +{ + struct grub_video_i386_vbeblit_info target; + + /* Make sure there is something to do. */ + if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + return GRUB_ERR_NONE; + if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + return GRUB_ERR_NONE; + + /* Do not allow drawing out of viewport. */ + if (x < 0) + { + width += x; + x = 0; + } + if (y < 0) + { + height += y; + y = 0; + } + + if ((x + width) > render_target->viewport.width) + width = render_target->viewport.width - x; + if ((y + height) > render_target->viewport.height) + height = render_target->viewport.height - y; + + /* Add viewport offset. */ + x += render_target->viewport.x; + y += render_target->viewport.y; + + /* Use vbeblit_info to encapsulate rendering. */ + target.mode_info = &render_target->mode_info; + target.data = render_target->data; + + /* Try to figure out more optimized version. Note that color is already + mapped to target format so we can make assumptions based on that. */ + if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbefill_direct32 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + grub_video_i386_vbefill_direct32 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + grub_video_i386_vbefill_direct24 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565) + { + grub_video_i386_vbefill_direct16 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565) + { + grub_video_i386_vbefill_direct16 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbefill_direct8 (&target, color, x, y, + width, height); + return GRUB_ERR_NONE; + } + + /* No optimized version found, use default (slow) filler. */ + grub_video_i386_vbefill (&target, color, x, y, width, height); + + return GRUB_ERR_NONE; +} + +/* NOTE: This function assumes that given coordinates are within bounds of + handled data. */ +static void +common_blitter (struct grub_video_i386_vbeblit_info *target, + struct grub_video_i386_vbeblit_info *source, + enum grub_video_blit_operators oper, int x, int y, + unsigned int width, unsigned int height, + int offset_x, int offset_y) +{ + if (oper == GRUB_VIDEO_BLIT_REPLACE) + { + /* Try to figure out more optimized version for replace operator. */ + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + grub_video_i386_vbeblit_replace_directN (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888) + { + grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbeblit_replace_index_RGBX8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888) + { + grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + grub_video_i386_vbeblit_replace_directN (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbeblit_replace_index_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbeblit_replace_directN (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbeblit_replace_directN (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + + /* No optimized replace operator found, use default (slow) blitter. */ + grub_video_i386_vbeblit_replace (target, source, x, y, width, height, + offset_x, offset_y); + } + else + { + /* Try to figure out more optimized blend operator. */ + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888) + { + grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbeblit_blend_index_RGBA8888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + else if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + /* Note: There is really no alpha information here, so blend is + changed to replace. */ + + if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888) + { + grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888) + { + grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_888) + { + grub_video_i386_vbeblit_replace_BGR888_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888) + { + grub_video_i386_vbeblit_replace_directN (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + else if (target->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR) + { + grub_video_i386_vbeblit_replace_index_RGB888 (target, source, + x, y, width, height, + offset_x, offset_y); + return; + } + } + + /* No optimized blend operation found, use default (slow) blitter. */ + grub_video_i386_vbeblit_blend (target, source, x, y, width, height, + offset_x, offset_y); + } +} + +static grub_err_t +grub_video_vbe_blit_bitmap (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, int x, int y, + int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + struct grub_video_i386_vbeblit_info source; + struct grub_video_i386_vbeblit_info target; + + /* Make sure there is something to do. */ + if ((width == 0) || (height == 0)) + return GRUB_ERR_NONE; + if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + return GRUB_ERR_NONE; + if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + return GRUB_ERR_NONE; + if ((x + (int)bitmap->mode_info.width) < 0) + return GRUB_ERR_NONE; + if ((y + (int)bitmap->mode_info.height) < 0) + return GRUB_ERR_NONE; + if ((offset_x >= (int)bitmap->mode_info.width) + || (offset_x + (int)width < 0)) + return GRUB_ERR_NONE; + if ((offset_y >= (int)bitmap->mode_info.height) + || (offset_y + (int)height < 0)) + return GRUB_ERR_NONE; + + /* If we have negative coordinates, optimize drawing to minimum. */ + if (offset_x < 0) + { + width += offset_x; + x -= offset_x; + offset_x = 0; + } + + if (offset_y < 0) + { + height += offset_y; + y -= offset_y; + offset_y = 0; + } + + if (x < 0) + { + width += x; + offset_x -= x; + x = 0; + } + + if (y < 0) + { + height += y; + offset_y -= y; + y = 0; + } + + /* Do not allow drawing out of viewport. */ + if ((x + width) > render_target->viewport.width) + width = render_target->viewport.width - x; + if ((y + height) > render_target->viewport.height) + height = render_target->viewport.height - y; + + if ((offset_x + width) > bitmap->mode_info.width) + width = bitmap->mode_info.width - offset_x; + if ((offset_y + height) > bitmap->mode_info.height) + height = bitmap->mode_info.height - offset_y; + + /* Limit drawing to source render target dimensions. */ + if (width > bitmap->mode_info.width) + width = bitmap->mode_info.width; + + if (height > bitmap->mode_info.height) + height = bitmap->mode_info.height; + + /* Add viewport offset. */ + x += render_target->viewport.x; + y += render_target->viewport.y; + + /* Use vbeblit_info to encapsulate rendering. */ + source.mode_info = &bitmap->mode_info; + source.data = bitmap->data; + target.mode_info = &render_target->mode_info; + target.data = render_target->data; + + /* Do actual blitting. */ + common_blitter (&target, &source, oper, x, y, width, height, + offset_x, offset_y); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_blit_render_target (struct grub_video_render_target *source, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + struct grub_video_i386_vbeblit_info source_info; + struct grub_video_i386_vbeblit_info target_info; + + /* Make sure there is something to do. */ + if ((width == 0) || (height == 0)) + return GRUB_ERR_NONE; + if ((x >= (int)render_target->viewport.width) || (x + (int)width < 0)) + return GRUB_ERR_NONE; + if ((y >= (int)render_target->viewport.height) || (y + (int)height < 0)) + return GRUB_ERR_NONE; + if ((x + (int)source->mode_info.width) < 0) + return GRUB_ERR_NONE; + if ((y + (int)source->mode_info.height) < 0) + return GRUB_ERR_NONE; + if ((offset_x >= (int)source->mode_info.width) + || (offset_x + (int)width < 0)) + return GRUB_ERR_NONE; + if ((offset_y >= (int)source->mode_info.height) + || (offset_y + (int)height < 0)) + return GRUB_ERR_NONE; + + /* If we have negative coordinates, optimize drawing to minimum. */ + if (offset_x < 0) + { + width += offset_x; + x -= offset_x; + offset_x = 0; + } + + if (offset_y < 0) + { + height += offset_y; + y -= offset_y; + offset_y = 0; + } + + if (x < 0) + { + width += x; + offset_x -= x; + x = 0; + } + + if (y < 0) + { + height += y; + offset_y -= y; + y = 0; + } + + /* Do not allow drawing out of viewport. */ + if ((x + width) > render_target->viewport.width) + width = render_target->viewport.width - x; + if ((y + height) > render_target->viewport.height) + height = render_target->viewport.height - y; + + if ((offset_x + width) > source->mode_info.width) + width = source->mode_info.width - offset_x; + if ((offset_y + height) > source->mode_info.height) + height = source->mode_info.height - offset_y; + + /* Limit drawing to source render target dimensions. */ + if (width > source->mode_info.width) + width = source->mode_info.width; + + if (height > source->mode_info.height) + height = source->mode_info.height; + + /* Add viewport offset. */ + x += render_target->viewport.x; + y += render_target->viewport.y; + + /* Use vbeblit_info to encapsulate rendering. */ + source_info.mode_info = &source->mode_info; + source_info.data = source->data; + target_info.mode_info = &render_target->mode_info; + target_info.data = render_target->data; + + /* Do actual blitting. */ + common_blitter (&target_info, &source_info, oper, x, y, width, height, + offset_x, offset_y); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_scroll (grub_video_color_t color, int dx, int dy) +{ + int width; + int height; + int src_x; + int src_y; + int dst_x; + int dst_y; + + /* 1. Check if we have something to do. */ + if ((dx == 0) && (dy == 0)) + return GRUB_ERR_NONE; + + width = render_target->viewport.width - grub_abs (dx); + height = render_target->viewport.height - grub_abs (dy); + + if (dx < 0) + { + src_x = render_target->viewport.x - dx; + dst_x = render_target->viewport.x; + } + else + { + src_x = render_target->viewport.x; + dst_x = render_target->viewport.x + dx; + } + + if (dy < 0) + { + src_y = render_target->viewport.y - dy; + dst_y = render_target->viewport.y; + } + else + { + src_y = render_target->viewport.y; + dst_y = render_target->viewport.y + dy; + } + + /* 2. Check if there is need to copy data. */ + if ((grub_abs (dx) < render_target->viewport.width) + && (grub_abs (dy) < render_target->viewport.height)) + { + /* 3. Move data in render target. */ + struct grub_video_i386_vbeblit_info target; + grub_uint8_t *src; + grub_uint8_t *dst; + int j; + + target.mode_info = &render_target->mode_info; + target.data = render_target->data; + + /* Check vertical direction of the move. */ + if (dy <= 0) + /* 3a. Move data upwards. */ + for (j = 0; j < height; j++) + { + dst = grub_video_vbe_get_video_ptr (&target, dst_x, dst_y + j); + src = grub_video_vbe_get_video_ptr (&target, src_x, src_y + j); + grub_memmove (dst, src, + width * target.mode_info->bytes_per_pixel); + } + else + /* 3b. Move data downwards. */ + for (j = (height - 1); j >= 0; j--) + { + dst = grub_video_vbe_get_video_ptr (&target, dst_x, dst_y + j); + src = grub_video_vbe_get_video_ptr (&target, src_x, src_y + j); + grub_memmove (dst, src, + width * target.mode_info->bytes_per_pixel); + } + } + + /* 4. Fill empty space with specified color. In this implementation + there might be colliding areas but at the moment there is no need + to optimize this. */ + + /* 4a. Fill top & bottom parts. */ + if (dy > 0) + grub_video_vbe_fill_rect (color, 0, 0, render_target->viewport.width, dy); + else if (dy < 0) + { + if (render_target->viewport.height < grub_abs (dy)) + dy = -render_target->viewport.height; + + grub_video_vbe_fill_rect (color, 0, render_target->viewport.height + dy, + render_target->viewport.width, -dy); + } + + /* 4b. Fill left & right parts. */ + if (dx > 0) + grub_video_vbe_fill_rect (color, 0, 0, + dx, render_target->viewport.height); + else if (dx < 0) + { + if (render_target->viewport.width < grub_abs (dx)) + dx = -render_target->viewport.width; + + grub_video_vbe_fill_rect (color, render_target->viewport.width + dx, 0, + -dx, render_target->viewport.height); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_create_render_target (struct grub_video_render_target **result, + unsigned int width, unsigned int height, + unsigned int mode_type __attribute__ ((unused))) +{ + struct grub_video_render_target *target; + unsigned int size; + + /* Validate arguments. */ + if ((! result) + || (width == 0) + || (height == 0)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid argument given."); + + /* Allocate memory for render target. */ + target = grub_malloc (sizeof (struct grub_video_render_target)); + if (! target) + return grub_errno; + + /* TODO: Implement other types too. + Currently only 32bit render targets are supported. */ + + /* Mark render target as allocated. */ + target->is_allocated = 1; + + /* Maximize viewport. */ + target->viewport.x = 0; + target->viewport.y = 0; + target->viewport.width = width; + target->viewport.height = height; + + /* Setup render target format. */ + target->mode_info.width = width; + target->mode_info.height = height; + target->mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA; + target->mode_info.bpp = 32; + target->mode_info.bytes_per_pixel = 4; + target->mode_info.pitch = target->mode_info.bytes_per_pixel * width; + target->mode_info.number_of_colors = 256; /* Emulated palette. */ + target->mode_info.red_mask_size = 8; + target->mode_info.red_field_pos = 0; + target->mode_info.green_mask_size = 8; + target->mode_info.green_field_pos = 8; + target->mode_info.blue_mask_size = 8; + target->mode_info.blue_field_pos = 16; + target->mode_info.reserved_mask_size = 8; + target->mode_info.reserved_field_pos = 24; + + target->mode_info.blit_format = grub_video_get_blit_format (&target->mode_info); + + /* Calculate size needed for the data. */ + size = (width * target->mode_info.bytes_per_pixel) * height; + + target->data = grub_malloc (size); + if (! target->data) + { + grub_free (target); + return grub_errno; + } + + /* Clear render target with black and maximum transparency. */ + grub_memset (target->data, 0, size); + + /* TODO: Add render target to render target list. */ + + /* Save result to caller. */ + *result = target; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_delete_render_target (struct grub_video_render_target *target) +{ + /* If there is no target, then just return without error. */ + if (! target) + return GRUB_ERR_NONE; + + /* TODO: Delist render target fron render target list. */ + + /* If this is software render target, free it's memory. */ + if (target->is_allocated) + grub_free (target->data); + + /* Free render target. */ + grub_free (target); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_FRONT_BUFFER) + { + render_target = &framebuffer.render_target; + + return GRUB_ERR_NONE; + } + + if (target == GRUB_VIDEO_RENDER_TARGET_BACK_BUFFER) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "double buffering not implemented yet."); + + if (! target->data) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid render target given."); + + render_target = target; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vbe_get_active_render_target (struct grub_video_render_target **target) +{ + *target = render_target; + + return GRUB_ERR_NONE; +} + +static struct grub_video_adapter grub_video_vbe_adapter = + { + .name = "VESA BIOS Extension Video Driver", + + .init = grub_video_vbe_init, + .fini = grub_video_vbe_fini, + .setup = grub_video_vbe_setup, + .get_info = grub_video_vbe_get_info, + .set_palette = grub_video_vbe_set_palette, + .get_palette = grub_video_vbe_get_palette, + .set_viewport = grub_video_vbe_set_viewport, + .get_viewport = grub_video_vbe_get_viewport, + .map_color = grub_video_vbe_map_color, + .map_rgb = grub_video_vbe_map_rgb, + .map_rgba = grub_video_vbe_map_rgba, + .unmap_color = grub_video_vbe_unmap_color, + .fill_rect = grub_video_vbe_fill_rect, + .blit_bitmap = grub_video_vbe_blit_bitmap, + .blit_render_target = grub_video_vbe_blit_render_target, + .scroll = grub_video_vbe_scroll, + .swap_buffers = grub_video_vbe_swap_buffers, + .create_render_target = grub_video_vbe_create_render_target, + .delete_render_target = grub_video_vbe_delete_render_target, + .set_active_render_target = grub_video_vbe_set_active_render_target, + .get_active_render_target = grub_video_vbe_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_i386_pc_vbe) +{ + grub_video_register (&grub_video_vbe_adapter); +} + +GRUB_MOD_FINI(video_i386_pc_vbe) +{ + grub_video_unregister (&grub_video_vbe_adapter); +} diff --git a/video/i386/pc/vbeblit.c b/video/i386/pc/vbeblit.c new file mode 100644 index 0000000..4121bfe --- /dev/null +++ b/video/i386/pc/vbeblit.c @@ -0,0 +1,828 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* SPECIAL NOTES! + + Please note following when reading the code below: + + - In this driver we assume that every memory can be accessed by same memory + bus. If there are different address spaces do not use this code as a base + code for other archs. + + - Every function in this code assumes that bounds checking has been done in + previous phase and they are opted out in here. */ + +#include +#include +#include +#include +#include +#include + +/* Generic replacing blitter (slow). Works for every supported format. */ +void +grub_video_i386_vbeblit_replace (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y) +{ + int i; + int j; + grub_uint8_t src_red; + grub_uint8_t src_green; + grub_uint8_t src_blue; + grub_uint8_t src_alpha; + grub_video_color_t src_color; + grub_video_color_t dst_color; + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + src_color = get_pixel (src, i + offset_x, j + offset_y); + + grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green, + &src_blue, &src_alpha); + + dst_color = grub_video_vbe_map_rgba (src_red, src_green, + src_blue, src_alpha); + + set_pixel (dst, x + i, y + j, dst_color); + } + } +} + +/* Block copy replacing blitter. Works with modes multiple of 8 bits. */ +void +grub_video_i386_vbeblit_replace_directN (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y) +{ + int j; + grub_uint32_t *srcptr; + grub_uint32_t *dstptr; + int bpp; + + bpp = src->mode_info->bytes_per_pixel; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j); + + grub_memmove (dstptr, srcptr, width * bpp); + } +} + +/* Optimized replacing blitter for RGBX8888 to BGRX8888. */ +void +grub_video_i386_vbeblit_replace_BGRX8888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + int i; + int j; + grub_uint8_t *srcptr; + grub_uint8_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint8_t r = *srcptr++; + grub_uint8_t g = *srcptr++; + grub_uint8_t b = *srcptr++; + grub_uint8_t a = *srcptr++; + + *dstptr++ = b; + *dstptr++ = g; + *dstptr++ = r; + *dstptr++ = a; + } + + srcptr += srcrowskip; + dstptr += dstrowskip; + } +} + +/* Optimized replacing blitter for RGB888 to BGRX8888. */ +void +grub_video_i386_vbeblit_replace_BGRX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + int i; + int j; + grub_uint8_t *srcptr; + grub_uint8_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint8_t r = *srcptr++; + grub_uint8_t g = *srcptr++; + grub_uint8_t b = *srcptr++; + + *dstptr++ = b; + *dstptr++ = g; + *dstptr++ = r; + + /* Set alpha component as opaque. */ + *dstptr++ = 255; + } + + srcptr += srcrowskip; + dstptr += dstrowskip; + } +} + +/* Optimized replacing blitter for RGBX8888 to BGR888. */ +void +grub_video_i386_vbeblit_replace_BGR888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + int i; + int j; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint32_t color; + grub_uint8_t sr; + grub_uint8_t sg; + grub_uint8_t sb; + + color = *srcptr++; + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + *dstptr++ = sb; + *dstptr++ = sg; + *dstptr++ = sr; + } + + srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); + dstptr += dstrowskip; + } +} + +/* Optimized replacing blitter for RGB888 to BGR888. */ +void +grub_video_i386_vbeblit_replace_BGR888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + int i; + int j; + grub_uint8_t *srcptr; + grub_uint8_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint8_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint8_t r = *srcptr++; + grub_uint8_t g = *srcptr++; + grub_uint8_t b = *srcptr++; + + *dstptr++ = b; + *dstptr++ = g; + *dstptr++ = r; + } + + srcptr += srcrowskip; + dstptr += dstrowskip; + } +} + +/* Optimized replacing blitter for RGB888 to RGBX8888. */ +void +grub_video_i386_vbeblit_replace_RGBX8888_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint8_t *srcptr; + grub_uint32_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + sr = *srcptr++; + sg = *srcptr++; + sb = *srcptr++; + + /* Set alpha as opaque. */ + color = 0xFF000000 | (sb << 16) | (sg << 8) | sr; + + *dstptr++ = color; + } + } +} + +/* Optimized replacing blitter for RGBX8888 to RGB888. */ +void +grub_video_i386_vbeblit_replace_RGB888_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + color = *srcptr++; + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + *dstptr++ = sr; + *dstptr++ = sg; + *dstptr++ = sb; + } + } +} + +/* Optimized replacing blitter for RGBX8888 to indexed color. */ +void +grub_video_i386_vbeblit_replace_index_RGBX8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + color = *srcptr++; + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + color = grub_video_vbe_map_rgb(sr, sg, sb); + *dstptr++ = color & 0xFF; + } + } +} + +/* Optimized replacing blitter for RGB888 to indexed color. */ +void +grub_video_i386_vbeblit_replace_index_RGB888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint8_t *srcptr; + grub_uint8_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint8_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + sr = *srcptr++; + sg = *srcptr++; + sb = *srcptr++; + + color = grub_video_vbe_map_rgb(sr, sg, sb); + + *dstptr++ = color & 0xFF; + } + } +} + +/* Generic blending blitter. Works for every supported format. */ +void +grub_video_i386_vbeblit_blend (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, int width, int height, + int offset_x, int offset_y) +{ + int i; + int j; + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint8_t src_red; + grub_uint8_t src_green; + grub_uint8_t src_blue; + grub_uint8_t src_alpha; + grub_uint8_t dst_red; + grub_uint8_t dst_green; + grub_uint8_t dst_blue; + grub_uint8_t dst_alpha; + grub_video_color_t src_color; + grub_video_color_t dst_color; + + src_color = get_pixel (src, i + offset_x, j + offset_y); + grub_video_vbe_unmap_color_int (src, src_color, &src_red, &src_green, + &src_blue, &src_alpha); + + if (src_alpha == 0) + continue; + + if (src_alpha == 255) + { + dst_color = grub_video_vbe_map_rgba (src_red, src_green, + src_blue, src_alpha); + set_pixel (dst, x + i, y + j, dst_color); + continue; + } + + dst_color = get_pixel (dst, x + i, y + j); + + grub_video_vbe_unmap_color_int (dst, dst_color, &dst_red, + &dst_green, &dst_blue, &dst_alpha); + + dst_red = (((src_red * src_alpha) + + (dst_red * (255 - src_alpha))) / 255); + dst_green = (((src_green * src_alpha) + + (dst_green * (255 - src_alpha))) / 255); + dst_blue = (((src_blue * src_alpha) + + (dst_blue * (255 - src_alpha))) / 255); + + dst_alpha = src_alpha; + dst_color = grub_video_vbe_map_rgba (dst_red, dst_green, dst_blue, + dst_alpha); + + set_pixel (dst, x + i, y + j, dst_color); + } + } +} + +/* Optimized blending blitter for RGBA8888 to BGRA8888. */ +void +grub_video_i386_vbeblit_blend_BGRA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t *srcptr; + grub_uint32_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + int i; + int j; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint32_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint32_t color; + unsigned int sr; + unsigned int sg; + unsigned int sb; + unsigned int a; + unsigned int dr; + unsigned int dg; + unsigned int db; + + color = *srcptr++; + + a = color >> 24; + + if (a == 0) + { + /* Skip transparent source pixels. */ + dstptr++; + continue; + } + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + if (a == 255) + { + /* Opaque pixel shortcut. */ + dr = sr; + dg = sg; + db = sb; + } + else + { + /* General pixel color blending. */ + color = *dstptr; + + dr = (color >> 16) & 0xFF; + dr = (dr * (255 - a) + sr * a) / 255; + dg = (color >> 8) & 0xFF; + dg = (dg * (255 - a) + sg * a) / 255; + db = (color >> 0) & 0xFF; + db = (db * (255 - a) + sb * a) / 255; + } + + color = (a << 24) | (dr << 16) | (dg << 8) | db; + + *dstptr++ = color; + } + + srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); + dstptr = (grub_uint32_t *) (((grub_uint8_t *) dstptr) + dstrowskip); + } +} + +/* Optimized blending blitter for RGBA8888 to BGR888. */ +void +grub_video_i386_vbeblit_blend_BGR888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int srcrowskip; + unsigned int dstrowskip; + int i; + int j; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + srcrowskip = src->mode_info->pitch - src->mode_info->bytes_per_pixel * width; + dstrowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + srcptr = (grub_uint32_t *) get_data_ptr (src, offset_x, offset_y); + dstptr = (grub_uint8_t *) get_data_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + grub_uint32_t color; + unsigned int sr; + unsigned int sg; + unsigned int sb; + unsigned int a; + unsigned int dr; + unsigned int dg; + unsigned int db; + + color = *srcptr++; + + a = color >> 24; + + if (a == 0) + { + /* Skip transparent source pixels. */ + dstptr += 3; + continue; + } + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + if (a == 255) + { + /* Opaque pixel shortcut. */ + dr = sr; + dg = sg; + db = sb; + } + else + { + /* General pixel color blending. */ + color = *dstptr; + + db = dstptr[0]; + db = (db * (255 - a) + sb * a) / 255; + dg = dstptr[1]; + dg = (dg * (255 - a) + sg * a) / 255; + dr = dstptr[2]; + dr = (dr * (255 - a) + sr * a) / 255; + } + + *dstptr++ = db; + *dstptr++ = dg; + *dstptr++ = dr; + } + + srcptr = (grub_uint32_t *) (((grub_uint8_t *) srcptr) + srcrowskip); + dstptr += dstrowskip; + } +} + +/* Optimized blending blitter for RGBA888 to RGBA8888. */ +void +grub_video_i386_vbeblit_blend_RGBA8888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint32_t *srcptr; + grub_uint32_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + unsigned int a; + unsigned int dr; + unsigned int dg; + unsigned int db; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint32_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + color = *srcptr++; + + a = color >> 24; + + if (a == 0) + { + dstptr++; + continue; + } + + if (a == 255) + { + *dstptr++ = color; + continue; + } + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + color = *dstptr; + + dr = (color >> 0) & 0xFF; + dg = (color >> 8) & 0xFF; + db = (color >> 16) & 0xFF; + + dr = (dr * (255 - a) + sr * a) / 255; + dg = (dg * (255 - a) + sg * a) / 255; + db = (db * (255 - a) + sb * a) / 255; + + color = (a << 24) | (db << 16) | (dg << 8) | dr; + + *dstptr++ = color; + } + } +} + +/* Optimized blending blitter for RGBA8888 to RGB888. */ +void +grub_video_i386_vbeblit_blend_RGB888_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + unsigned int a; + unsigned int dr; + unsigned int dg; + unsigned int db; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + color = *srcptr++; + + a = color >> 24; + + if (a == 0) + { + dstptr += 3; + continue; + } + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + if (a == 255) + { + *dstptr++ = sr; + *dstptr++ = sg; + *dstptr++ = sb; + + continue; + } + + dr = dstptr[0]; + dg = dstptr[1]; + db = dstptr[2]; + + dr = (dr * (255 - a) + sr * a) / 255; + dg = (dg * (255 - a) + sg * a) / 255; + db = (db * (255 - a) + sb * a) / 255; + + *dstptr++ = dr; + *dstptr++ = dg; + *dstptr++ = db; + } + } +} + +/* Optimized blending blitter for RGBA8888 to indexed color. */ +void +grub_video_i386_vbeblit_blend_index_RGBA8888 (struct grub_video_i386_vbeblit_info *dst, + struct grub_video_i386_vbeblit_info *src, + int x, int y, + int width, int height, + int offset_x, int offset_y) +{ + grub_uint32_t color; + int i; + int j; + grub_uint32_t *srcptr; + grub_uint8_t *dstptr; + unsigned int sr; + unsigned int sg; + unsigned int sb; + unsigned int a; + unsigned char dr; + unsigned char dg; + unsigned char db; + unsigned char da; + + for (j = 0; j < height; j++) + { + srcptr = (grub_uint32_t *)get_data_ptr (src, offset_x, j + offset_y); + dstptr = (grub_uint8_t *)get_data_ptr (dst, x, y + j); + + for (i = 0; i < width; i++) + { + color = *srcptr++; + + a = color >> 24; + + if (a == 0) + { + dstptr++; + continue; + } + + sr = (color >> 0) & 0xFF; + sg = (color >> 8) & 0xFF; + sb = (color >> 16) & 0xFF; + + if (a == 255) + { + color = grub_video_vbe_map_rgb(sr, sg, sb); + *dstptr++ = color & 0xFF; + continue; + } + + grub_video_vbe_unmap_color_int (dst, *dstptr, &dr, &dg, &db, &da); + + dr = (dr * (255 - a) + sr * a) / 255; + dg = (dg * (255 - a) + sg * a) / 255; + db = (db * (255 - a) + sb * a) / 255; + + color = grub_video_vbe_map_rgb(dr, dg, db); + + *dstptr++ = color & 0xFF; + } + } +} diff --git a/video/i386/pc/vbefill.c b/video/i386/pc/vbefill.c new file mode 100644 index 0000000..3a98a71 --- /dev/null +++ b/video/i386/pc/vbefill.c @@ -0,0 +1,177 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* SPECIAL NOTES! + + Please note following when reading the code below: + + - In this driver we assume that every memory can be accessed by same memory + bus. If there are different address spaces do not use this code as a base + code for other archs. + + - Every function in this code assumes that bounds checking has been done in + previous phase and they are opted out in here. */ + +#include +#include +#include +#include +#include + +/* Generic filler that works for every supported mode. */ +void +grub_video_i386_vbefill (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height) +{ + int i; + int j; + + for (j = 0; j < height; j++) + for (i = 0; i < width; i++) + set_pixel (dst, x+i, y+j, color); +} + +/* Optimized filler for direct color 32 bit modes. It is assumed that color + is already mapped to destination format. */ +void +grub_video_i386_vbefill_direct32 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height) +{ + int i; + int j; + grub_uint32_t *dstptr; + grub_size_t rowskip; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + /* Get the start address. */ + dstptr = (grub_uint32_t *) grub_video_vbe_get_video_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + *dstptr++ = color; + + /* Advance the dest pointer to the right location on the next line. */ + dstptr = (grub_uint32_t *) (((char *) dstptr) + rowskip); + } +} + +/* Optimized filler for direct color 24 bit modes. It is assumed that color + is already mapped to destination format. */ +void +grub_video_i386_vbefill_direct24 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height) +{ + int i; + int j; + grub_size_t rowskip; + grub_uint8_t *dstptr; + grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF); + grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF); + grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF); + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + /* Get the start address. */ + dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + *dstptr++ = fill0; + *dstptr++ = fill1; + *dstptr++ = fill2; + } + + /* Advance the dest pointer to the right location on the next line. */ + dstptr += rowskip; + } +} + +/* Optimized filler for direct color 16 bit modes. It is assumed that color + is already mapped to destination format. */ +void +grub_video_i386_vbefill_direct16 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height) +{ + int i; + int j; + grub_size_t rowskip; + grub_uint8_t *dstptr; + grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF); + grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF); + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + /* Get the start address. */ + dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + *dstptr++ = fill0; + *dstptr++ = fill1; + } + + /* Advance the dest pointer to the right location on the next line. */ + dstptr += rowskip; + } +} + +/* Optimized filler for index color. It is assumed that color + is already mapped to destination format. */ +void +grub_video_i386_vbefill_direct8 (struct grub_video_i386_vbeblit_info *dst, + grub_video_color_t color, int x, int y, + int width, int height) +{ + int i; + int j; + grub_size_t rowskip; + grub_uint8_t *dstptr; + grub_uint8_t fill = (grub_uint8_t)color & 0xFF; + + /* Calculate the number of bytes to advance from the end of one line + to the beginning of the next line. */ + rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + + /* Get the start address. */ + dstptr = (grub_uint8_t *) grub_video_vbe_get_video_ptr (dst, x, y); + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + *dstptr++ = fill; + + /* Advance the dest pointer to the right location on the next line. */ + dstptr += rowskip; + } +} diff --git a/video/i386/pc/vbeutil.c b/video/i386/pc/vbeutil.c new file mode 100644 index 0000000..1040dc9 --- /dev/null +++ b/video/i386/pc/vbeutil.c @@ -0,0 +1,177 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +grub_uint8_t * +get_data_ptr (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y) +{ + grub_uint8_t *ptr = 0; + + switch (source->mode_info->bpp) + { + case 32: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 4; + break; + + case 24: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 3; + break; + + case 16: + case 15: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x * 2; + break; + + case 8: + ptr = (grub_uint8_t *)source->data + + y * source->mode_info->pitch + + x; + break; + + case 1: + /* For 1-bit bitmaps, addressing needs to be done at the bit level + and it doesn't make sense, in general, to ask for a pointer + to a particular pixel's data. */ + break; + } + + return ptr; +} + +grub_video_color_t +get_pixel (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y) +{ + grub_video_color_t color = 0; + + switch (source->mode_info->bpp) + { + case 32: + color = *(grub_uint32_t *)get_data_ptr (source, x, y); + break; + + case 24: + { + grub_uint8_t *ptr; + ptr = get_data_ptr (source, x, y); + color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); + } + break; + + case 16: + case 15: + color = *(grub_uint16_t *)get_data_ptr (source, x, y); + break; + + case 8: + color = *(grub_uint8_t *)get_data_ptr (source, x, y); + break; + + case 1: + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) + { + int bit_index = y * source->mode_info->width + x; + grub_uint8_t *ptr = (grub_uint8_t *)source->data + + bit_index / 8; + int bit_pos = 7 - bit_index % 8; + color = (*ptr >> bit_pos) & 0x01; + } + break; + + default: + break; + } + + return color; +} + +void +set_pixel (struct grub_video_i386_vbeblit_info *source, + unsigned int x, unsigned int y, grub_video_color_t color) +{ + switch (source->mode_info->bpp) + { + case 32: + { + grub_uint32_t *ptr; + + ptr = (grub_uint32_t *)get_data_ptr (source, x, y); + + *ptr = color; + } + break; + + case 24: + { + grub_uint8_t *ptr; + grub_uint8_t *colorptr = (grub_uint8_t *)&color; + + ptr = get_data_ptr (source, x, y); + + ptr[0] = colorptr[0]; + ptr[1] = colorptr[1]; + ptr[2] = colorptr[2]; + } + break; + + case 16: + case 15: + { + grub_uint16_t *ptr; + + ptr = (grub_uint16_t *)get_data_ptr (source, x, y); + + *ptr = (grub_uint16_t) (color & 0xFFFF); + } + break; + + case 8: + { + grub_uint8_t *ptr; + + ptr = (grub_uint8_t *)get_data_ptr (source, x, y); + + *ptr = (grub_uint8_t) (color & 0xFF); + } + break; + + case 1: + if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) + { + int bit_index = y * source->mode_info->width + x; + grub_uint8_t *ptr = (grub_uint8_t *)source->data + + bit_index / 8; + int bit_pos = 7 - bit_index % 8; + *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos); + } + break; + + default: + break; + } +} diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c new file mode 100644 index 0000000..327c9f9 --- /dev/null +++ b/video/readers/jpeg.c @@ -0,0 +1,748 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Uncomment following define to enable JPEG debug. */ +//#define JPEG_DEBUG + +#define JPEG_ESC_CHAR 0xFF + +#define JPEG_SAMPLING_1x1 0x11 + +#define JPEG_MARKER_SOI 0xd8 +#define JPEG_MARKER_EOI 0xd9 +#define JPEG_MARKER_DHT 0xc4 +#define JPEG_MARKER_DQT 0xdb +#define JPEG_MARKER_SOF0 0xc0 +#define JPEG_MARKER_SOS 0xda + +#define SHIFT_BITS 8 +#define CONST(x) ((int) ((x) * (1L << SHIFT_BITS) + 0.5)) + +#define JPEG_UNIT_SIZE 8 + +static const grub_uint8_t jpeg_zigzag_order[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +typedef int jpeg_data_unit_t[64]; + +struct grub_jpeg_data +{ + grub_file_t file; + struct grub_video_bitmap **bitmap; + + int image_width; + int image_height; + + grub_uint8_t *huff_value[4]; + int huff_offset[4][16]; + int huff_maxval[4][16]; + + grub_uint8_t quan_table[2][64]; + int comp_index[3][3]; + + jpeg_data_unit_t ydu[4]; + jpeg_data_unit_t crdu; + jpeg_data_unit_t cbdu; + + int vs, hs; + + int dc_value[3]; + + int bit_mask, bit_save; +}; + +static grub_uint8_t +grub_jpeg_get_byte (struct grub_jpeg_data *data) +{ + grub_uint8_t r; + + r = 0; + grub_file_read (data->file, (char *) &r, 1); + + return r; +} + +static grub_uint16_t +grub_jpeg_get_word (struct grub_jpeg_data *data) +{ + grub_uint16_t r; + + r = 0; + grub_file_read (data->file, (char *) &r, sizeof (grub_uint16_t)); + + return grub_be_to_cpu16 (r); +} + +static int +grub_jpeg_get_bit (struct grub_jpeg_data *data) +{ + int ret; + + if (data->bit_mask == 0) + { + data->bit_save = grub_jpeg_get_byte (data); + if (data->bit_save == JPEG_ESC_CHAR) + { + if (grub_jpeg_get_byte (data) != 0) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: invalid 0xFF in data stream"); + return 0; + } + } + data->bit_mask = 0x80; + } + + ret = ((data->bit_save & data->bit_mask) != 0); + data->bit_mask >>= 1; + return ret; +} + +static int +grub_jpeg_get_number (struct grub_jpeg_data *data, int num) +{ + int value, i, msb; + + if (num == 0) + return 0; + + msb = value = grub_jpeg_get_bit (data); + for (i = 1; i < num; i++) + value = (value << 1) + (grub_jpeg_get_bit (data) != 0); + if (!msb) + value += 1 - (1 << num); + + return value; +} + +static int +grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id) +{ + int code, i; + + code = 0; + for (i = 0; i < 16; i++) + { + code <<= 1; + if (grub_jpeg_get_bit (data)) + code++; + if (code < data->huff_maxval[id][i]) + return data->huff_value[id][code + data->huff_offset[id][i]]; + } + grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: huffman decode fails"); + return 0; +} + +static grub_err_t +grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) +{ + int id, ac, i, n, base, ofs; + grub_uint32_t next_marker; + grub_uint8_t count[16]; + + next_marker = data->file->offset; + next_marker += grub_jpeg_get_word (data); + + id = grub_jpeg_get_byte (data); + ac = (id >> 4); + id &= 0xF; + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many huffman tables"); + + if (grub_file_read (data->file, (char *) &count, sizeof (count)) != + sizeof (count)) + return grub_errno; + + n = 0; + for (i = 0; i < 16; i++) + n += count[i]; + + id += ac * 2; + data->huff_value[id] = grub_malloc (n); + if (grub_errno) + return grub_errno; + + if (grub_file_read (data->file, (char *) data->huff_value[id], n) != n) + return grub_errno; + + base = 0; + ofs = 0; + for (i = 0; i < 16; i++) + { + base += count[i]; + ofs += count[i]; + + data->huff_maxval[id][i] = base; + data->huff_offset[id][i] = ofs - base; + + base <<= 1; + } + + if (data->file->offset != next_marker) + grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table"); + + return grub_errno; +} + +static grub_err_t +grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) +{ + int id; + grub_uint32_t next_marker; + + next_marker = data->file->offset; + next_marker += grub_jpeg_get_word (data); + + id = grub_jpeg_get_byte (data); + if (id >= 0x10) /* Upper 4-bit is precision. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); + + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many quantization tables"); + + if (grub_file_read (data->file, (char *) &data->quan_table[id], 64) != 64) + return grub_errno; + + if (data->file->offset != next_marker) + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: extra byte in quantization table"); + + return grub_errno; +} + +static grub_err_t +grub_jpeg_decode_sof (struct grub_jpeg_data *data) +{ + int i, cc; + grub_uint32_t next_marker; + + next_marker = data->file->offset; + next_marker += grub_jpeg_get_word (data); + + if (grub_jpeg_get_byte (data) != 8) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); + + data->image_height = grub_jpeg_get_word (data); + data->image_width = grub_jpeg_get_word (data); + + if ((!data->image_height) || (!data->image_width)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size"); + + cc = grub_jpeg_get_byte (data); + if (cc != 3) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: component count must be 3"); + + for (i = 0; i < cc; i++) + { + int id, ss; + + id = grub_jpeg_get_byte (data) - 1; + if ((id < 0) || (id >= 3)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); + + ss = grub_jpeg_get_byte (data); /* Sampling factor. */ + if (!id) + { + data->vs = ss & 0xF; /* Vertical sampling. */ + data->hs = ss >> 4; /* Horizontal sampling. */ + if ((data->vs > 2) || (data->hs > 2)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: sampling method not supported"); + } + else if (ss != JPEG_SAMPLING_1x1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: sampling method not supported"); + data->comp_index[id][0] = grub_jpeg_get_byte (data); + } + + if (data->file->offset != next_marker) + grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sof"); + + return grub_errno; +} + +static void +grub_jpeg_idct_transform (jpeg_data_unit_t du) +{ + int *pd; + int i; + int t0, t1, t2, t3, t4, t5, t6, t7; + int v0, v1, v2, v3, v4; + + pd = du; + for (i = 0; i < JPEG_UNIT_SIZE; i++, pd++) + { + if ((pd[JPEG_UNIT_SIZE * 1] | pd[JPEG_UNIT_SIZE * 2] | + pd[JPEG_UNIT_SIZE * 3] | pd[JPEG_UNIT_SIZE * 4] | + pd[JPEG_UNIT_SIZE * 5] | pd[JPEG_UNIT_SIZE * 6] | + pd[JPEG_UNIT_SIZE * 7]) == 0) + { + pd[JPEG_UNIT_SIZE * 0] <<= SHIFT_BITS; + + pd[JPEG_UNIT_SIZE * 1] = pd[JPEG_UNIT_SIZE * 2] + = pd[JPEG_UNIT_SIZE * 3] = pd[JPEG_UNIT_SIZE * 4] + = pd[JPEG_UNIT_SIZE * 5] = pd[JPEG_UNIT_SIZE * 6] + = pd[JPEG_UNIT_SIZE * 7] = pd[JPEG_UNIT_SIZE * 0]; + + continue; + } + + t0 = pd[JPEG_UNIT_SIZE * 0]; + t1 = pd[JPEG_UNIT_SIZE * 2]; + t2 = pd[JPEG_UNIT_SIZE * 4]; + t3 = pd[JPEG_UNIT_SIZE * 6]; + + v4 = (t1 + t3) * CONST (0.541196100); + + v0 = ((t0 + t2) << SHIFT_BITS); + v1 = ((t0 - t2) << SHIFT_BITS); + v2 = v4 - t3 * CONST (1.847759065); + v3 = v4 + t1 * CONST (0.765366865); + + t0 = v0 + v3; + t3 = v0 - v3; + t1 = v1 + v2; + t2 = v1 - v2; + + t4 = pd[JPEG_UNIT_SIZE * 7]; + t5 = pd[JPEG_UNIT_SIZE * 5]; + t6 = pd[JPEG_UNIT_SIZE * 3]; + t7 = pd[JPEG_UNIT_SIZE * 1]; + + v0 = t4 + t7; + v1 = t5 + t6; + v2 = t4 + t6; + v3 = t5 + t7; + + v4 = (v2 + v3) * CONST (1.175875602); + + v0 *= CONST (0.899976223); + v1 *= CONST (2.562915447); + v2 = v2 * CONST (1.961570560) - v4; + v3 = v3 * CONST (0.390180644) - v4; + + t4 = t4 * CONST (0.298631336) - v0 - v2; + t5 = t5 * CONST (2.053119869) - v1 - v3; + t6 = t6 * CONST (3.072711026) - v1 - v2; + t7 = t7 * CONST (1.501321110) - v0 - v3; + + pd[JPEG_UNIT_SIZE * 0] = t0 + t7; + pd[JPEG_UNIT_SIZE * 7] = t0 - t7; + pd[JPEG_UNIT_SIZE * 1] = t1 + t6; + pd[JPEG_UNIT_SIZE * 6] = t1 - t6; + pd[JPEG_UNIT_SIZE * 2] = t2 + t5; + pd[JPEG_UNIT_SIZE * 5] = t2 - t5; + pd[JPEG_UNIT_SIZE * 3] = t3 + t4; + pd[JPEG_UNIT_SIZE * 4] = t3 - t4; + } + + pd = du; + for (i = 0; i < JPEG_UNIT_SIZE; i++, pd += JPEG_UNIT_SIZE) + { + if ((pd[1] | pd[2] | pd[3] | pd[4] | pd[5] | pd[6] | pd[7]) == 0) + { + pd[0] >>= (SHIFT_BITS + 3); + pd[1] = pd[2] = pd[3] = pd[4] = pd[5] = pd[6] = pd[7] = pd[0]; + continue; + } + + v4 = (pd[2] + pd[6]) * CONST (0.541196100); + + v0 = (pd[0] + pd[4]) << SHIFT_BITS; + v1 = (pd[0] - pd[4]) << SHIFT_BITS; + v2 = v4 - pd[6] * CONST (1.847759065); + v3 = v4 + pd[2] * CONST (0.765366865); + + t0 = v0 + v3; + t3 = v0 - v3; + t1 = v1 + v2; + t2 = v1 - v2; + + t4 = pd[7]; + t5 = pd[5]; + t6 = pd[3]; + t7 = pd[1]; + + v0 = t4 + t7; + v1 = t5 + t6; + v2 = t4 + t6; + v3 = t5 + t7; + + v4 = (v2 + v3) * CONST (1.175875602); + + v0 *= CONST (0.899976223); + v1 *= CONST (2.562915447); + v2 = v2 * CONST (1.961570560) - v4; + v3 = v3 * CONST (0.390180644) - v4; + + t4 = t4 * CONST (0.298631336) - v0 - v2; + t5 = t5 * CONST (2.053119869) - v1 - v3; + t6 = t6 * CONST (3.072711026) - v1 - v2; + t7 = t7 * CONST (1.501321110) - v0 - v3; + + pd[0] = (t0 + t7) >> (SHIFT_BITS * 2 + 3); + pd[7] = (t0 - t7) >> (SHIFT_BITS * 2 + 3); + pd[1] = (t1 + t6) >> (SHIFT_BITS * 2 + 3); + pd[6] = (t1 - t6) >> (SHIFT_BITS * 2 + 3); + pd[2] = (t2 + t5) >> (SHIFT_BITS * 2 + 3); + pd[5] = (t2 - t5) >> (SHIFT_BITS * 2 + 3); + pd[3] = (t3 + t4) >> (SHIFT_BITS * 2 + 3); + pd[4] = (t3 - t4) >> (SHIFT_BITS * 2 + 3); + } + + for (i = 0; i < JPEG_UNIT_SIZE * JPEG_UNIT_SIZE; i++) + { + du[i] += 128; + + if (du[i] < 0) + du[i] = 0; + if (du[i] > 255) + du[i] = 255; + } +} + +static void +grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) +{ + int pos, h1, h2, qt; + + grub_memset (du, 0, sizeof (jpeg_data_unit_t)); + + qt = data->comp_index[id][0]; + h1 = data->comp_index[id][1]; + h2 = data->comp_index[id][2]; + + data->dc_value[id] += + grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1)); + + du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; + pos = 1; + while (pos < 64) + { + int num, val; + + num = grub_jpeg_get_huff_code (data, h2); + if (!num) + break; + + val = grub_jpeg_get_number (data, num & 0xF); + num >>= 4; + pos += num; + du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; + pos++; + } + + grub_jpeg_idct_transform (du); +} + +static void +grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb) +{ + int dd; + + cr -= 128; + cb -= 128; + + /* Red */ + dd = yy + ((cr * CONST (1.402)) >> SHIFT_BITS); + if (dd < 0) + dd = 0; + if (dd > 255) + dd = 255; + *(rgb++) = dd; + + /* Green */ + dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS); + if (dd < 0) + dd = 0; + if (dd > 255) + dd = 255; + *(rgb++) = dd; + + /* Blue */ + dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS); + if (dd < 0) + dd = 0; + if (dd > 255) + dd = 255; + *(rgb++) = dd; +} + +static grub_err_t +grub_jpeg_decode_sos (struct grub_jpeg_data *data) +{ + int i, cc, r1, c1, nr1, nc1, vb, hb; + grub_uint8_t *ptr1; + grub_uint32_t data_offset; + + data_offset = data->file->offset; + data_offset += grub_jpeg_get_word (data); + + cc = grub_jpeg_get_byte (data); + + if (cc != 3) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: component count must be 3"); + + for (i = 0; i < cc; i++) + { + int id, ht; + + id = grub_jpeg_get_byte (data) - 1; + if ((id < 0) || (id >= 3)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); + + ht = grub_jpeg_get_byte (data); + data->comp_index[id][1] = (ht >> 4); + data->comp_index[id][2] = (ht & 0xF) + 2; + } + + grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ + grub_jpeg_get_word (data); + + if (data->file->offset != data_offset) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); + + if (grub_video_bitmap_create (data->bitmap, data->image_width, + data->image_height, + GRUB_VIDEO_BLIT_FORMAT_RGB_888)) + return grub_errno; + + data->bit_mask = 0x0; + + vb = data->vs * 8; + hb = data->hs * 8; + nr1 = (data->image_height + vb - 1) / vb; + nc1 = (data->image_width + hb - 1) / hb; + + ptr1 = (*data->bitmap)->data; + for (r1 = 0; r1 < nr1; + r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3) + for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3) + { + int r2, c2, nr2, nc2; + grub_uint8_t *ptr2; + + for (r2 = 0; r2 < data->vs; r2++) + for (c2 = 0; c2 < data->hs; c2++) + grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); + + grub_jpeg_decode_du (data, 1, data->cbdu); + grub_jpeg_decode_du (data, 2, data->crdu); + + if (grub_errno) + return grub_errno; + + nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb; + nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb; + + ptr2 = ptr1; + for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3) + for (c2 = 0; c2 < nc2; c2++, ptr2 += 3) + { + int i0, yy, cr, cb; + + i0 = (r2 / data->vs) * 8 + (c2 / data->hs); + cr = data->crdu[i0]; + cb = data->cbdu[i0]; + yy = + data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)]; + + grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2); + } + } + + return grub_errno; +} + +static grub_uint8_t +grub_jpeg_get_marker (struct grub_jpeg_data *data) +{ + grub_uint8_t r; + + r = grub_jpeg_get_byte (data); + + if (r != JPEG_ESC_CHAR) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid maker"); + return 0; + } + + return grub_jpeg_get_byte (data); +} + +static grub_err_t +grub_jpeg_decode_jpeg (struct grub_jpeg_data *data) +{ + if (grub_jpeg_get_marker (data) != JPEG_MARKER_SOI) /* Start Of Image. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid jpeg file"); + + while (grub_errno == 0) + { + grub_uint8_t marker; + + marker = grub_jpeg_get_marker (data); + if (grub_errno) + break; + +#ifdef JPEG_DEBUG + grub_printf ("jpeg marker: %x\n", marker); +#endif + + switch (marker) + { + case JPEG_MARKER_DHT: /* Define Huffman Table. */ + grub_jpeg_decode_huff_table (data); + break; + case JPEG_MARKER_DQT: /* Define Quantization Table. */ + grub_jpeg_decode_quan_table (data); + break; + case JPEG_MARKER_SOF0: /* Start Of Frame 0. */ + grub_jpeg_decode_sof (data); + break; + case JPEG_MARKER_SOS: /* Start Of Scan. */ + grub_jpeg_decode_sos (data); + break; + case JPEG_MARKER_EOI: /* End Of Image. */ + return grub_errno; + default: /* Skip unrecognized marker. */ + { + grub_uint16_t sz; + + sz = grub_jpeg_get_word (data); + if (grub_errno) + return (grub_errno); + grub_file_seek (data->file, data->file->offset + sz - 2); + } + } + } + + return grub_errno; +} + +static grub_err_t +grub_video_reader_jpeg (struct grub_video_bitmap **bitmap, + const char *filename) +{ + grub_file_t file; + struct grub_jpeg_data *data; + + file = grub_buffile_open (filename, 0); + if (!file) + return grub_errno; + + data = grub_malloc (sizeof (*data)); + if (data != NULL) + { + int i; + + grub_memset (data, 0, sizeof (*data)); + data->file = file; + data->bitmap = bitmap; + grub_jpeg_decode_jpeg (data); + + for (i = 0; i < 4; i++) + if (data->huff_value[i]) + grub_free (data->huff_value[i]); + + grub_free (data); + } + + if (grub_errno != GRUB_ERR_NONE) + { + grub_video_bitmap_destroy (*bitmap); + *bitmap = 0; + } + + grub_file_close (file); + return grub_errno; +} + +#if defined(JPEG_DEBUG) +static grub_err_t +grub_cmd_jpegtest (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_video_bitmap *bitmap = 0; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_video_reader_jpeg (&bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_video_bitmap_destroy (bitmap); + + return GRUB_ERR_NONE; +} +#endif + +static struct grub_video_bitmap_reader jpg_reader = { + .extension = ".jpg", + .reader = grub_video_reader_jpeg, + .next = 0 +}; + +static struct grub_video_bitmap_reader jpeg_reader = { + .extension = ".jpeg", + .reader = grub_video_reader_jpeg, + .next = 0 +}; + +GRUB_MOD_INIT (video_reader_jpeg) +{ + grub_video_bitmap_reader_register (&jpg_reader); + grub_video_bitmap_reader_register (&jpeg_reader); +#if defined(JPEG_DEBUG) + grub_register_command ("jpegtest", grub_cmd_jpegtest, + GRUB_COMMAND_FLAG_BOTH, "jpegtest FILE", + "Tests loading of JPEG bitmap.", 0); +#endif +} + +GRUB_MOD_FINI (video_reader_jpeg) +{ +#if defined(JPEG_DEBUG) + grub_unregister_command ("jpegtest"); +#endif + grub_video_bitmap_reader_unregister (&jpeg_reader); + grub_video_bitmap_reader_unregister (&jpg_reader); +} diff --git a/video/readers/png.c b/video/readers/png.c new file mode 100644 index 0000000..3364d56 --- /dev/null +++ b/video/readers/png.c @@ -0,0 +1,912 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Uncomment following define to enable PNG debug. */ +//#define PNG_DEBUG + +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGBA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAYA (PNG_COLOR_MASK_ALPHA) + +#define PNG_COMPRESSION_BASE 0 + +#define PNG_INTERLACE_NONE 0 +#define PNG_INTERLACE_ADAM7 1 + +#define PNG_FILTER_TYPE_BASE 0 + +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#define PNG_CHUNK_IHDR 0x49484452 +#define PNG_CHUNK_IDAT 0x49444154 +#define PNG_CHUNK_IEND 0x49454e44 + +#define Z_DEFLATED 8 +#define Z_FLAG_DICT 32 + +#define INFLATE_STORED 0 +#define INFLATE_FIXED 1 +#define INFLATE_DYNAMIC 2 + +#define WSIZE 0x8000 + +#define DEFLATE_HCLEN_BASE 4 +#define DEFLATE_HCLEN_MAX 19 +#define DEFLATE_HLIT_BASE 257 +#define DEFLATE_HLIT_MAX 288 +#define DEFLATE_HDIST_BASE 1 +#define DEFLATE_HDIST_MAX 30 + +#define DEFLATE_HUFF_LEN 16 + +struct huff_table +{ + int *values, *maxval, *offset; + int num_values, max_length; +}; + +struct grub_png_data +{ + grub_file_t file; + struct grub_video_bitmap **bitmap; + + int bit_count, bit_save; + + grub_uint32_t next_offset; + + int image_width, image_height, bpp, is_16bit, raw_bytes; + grub_uint8_t *image_data; + + int inside_idat, idat_remain; + + int code_values[DEFLATE_HLIT_MAX]; + int code_maxval[DEFLATE_HUFF_LEN]; + int code_offset[DEFLATE_HUFF_LEN]; + + int dist_values[DEFLATE_HDIST_MAX]; + int dist_maxval[DEFLATE_HUFF_LEN]; + int dist_offset[DEFLATE_HUFF_LEN]; + + struct huff_table code_table; + struct huff_table dist_table; + + grub_uint8_t slide[WSIZE]; + int wp; + + grub_uint8_t *cur_rgb; + + int cur_colume, cur_filter, first_line; +}; + +static grub_uint32_t +grub_png_get_dword (struct grub_png_data *data) +{ + grub_uint32_t r; + + r = 0; + grub_file_read (data->file, (char *) &r, sizeof (grub_uint32_t)); + + return grub_be_to_cpu32 (r); +} + +static grub_uint8_t +grub_png_get_byte (struct grub_png_data *data) +{ + grub_uint8_t r; + + if ((data->inside_idat) && (data->idat_remain == 0)) + { + grub_uint32_t len, type; + + do + { + /* Skip crc checksum. */ + grub_png_get_dword (data); + + if (data->file->offset != data->next_offset) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: chunk size error"); + return 0; + } + + len = grub_png_get_dword (data); + type = grub_png_get_dword (data); + if (type != PNG_CHUNK_IDAT) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: unexpected end of data"); + return 0; + } + + data->next_offset = data->file->offset + len + 4; + } + while (len == 0); + data->idat_remain = len; + } + + r = 0; + grub_file_read (data->file, (char *) &r, 1); + + if (data->inside_idat) + data->idat_remain--; + + return r; +} + +static int +grub_png_get_bits (struct grub_png_data *data, int num) +{ + int code, shift; + + if (data->bit_count == 0) + { + data->bit_save = grub_png_get_byte (data); + data->bit_count = 8; + } + + code = 0; + shift = 0; + while (grub_errno == 0) + { + int n; + + n = data->bit_count; + if (n > num) + n = num; + + code += (int) (data->bit_save & ((1 << n) - 1)) << shift; + num -= n; + if (!num) + { + data->bit_count -= n; + data->bit_save >>= n; + break; + } + + shift += n; + + data->bit_save = grub_png_get_byte (data); + data->bit_count = 8; + } + + return code; +} + +static grub_err_t +grub_png_decode_image_header (struct grub_png_data *data) +{ + int color_type; + int color_bits; + + data->image_width = grub_png_get_dword (data); + data->image_height = grub_png_get_dword (data); + + if ((!data->image_height) || (!data->image_width)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size"); + + color_bits = grub_png_get_byte (data); + if ((color_bits != 8) && (color_bits != 16)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: bit depth must be 8 or 16"); + data->is_16bit = (color_bits == 16); + + color_type = grub_png_get_byte (data); + if (color_type == PNG_COLOR_TYPE_RGB) + { + if (grub_video_bitmap_create (data->bitmap, data->image_width, + data->image_height, + GRUB_VIDEO_BLIT_FORMAT_RGB_888)) + return grub_errno; + data->bpp = 3; + } + else if (color_type == PNG_COLOR_TYPE_RGBA) + { + if (grub_video_bitmap_create (data->bitmap, data->image_width, + data->image_height, + GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)) + return grub_errno; + data->bpp = 4; + } + else + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: color type not supported"); + + if (data->is_16bit) + { + data->bpp <<= 1; + + data->image_data = grub_malloc (data->image_height * + data->image_width * data->bpp); + if (grub_errno) + return grub_errno; + + data->cur_rgb = data->image_data; + } + else + { + data->image_data = 0; + data->cur_rgb = (*data->bitmap)->data; + } + + data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp; + + data->cur_colume = 0; + data->first_line = 1; + + if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: compression method not supported"); + + if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: filter method not supported"); + + if (grub_png_get_byte (data) != PNG_INTERLACE_NONE) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: interlace method not supported"); + + /* Skip crc checksum. */ + grub_png_get_dword (data); + + return grub_errno; +} + +/* Order of the bit length code lengths. */ +static const grub_uint8_t bitorder[] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 +}; + +/* Copy lengths for literal codes 257..285. */ +static const int cplens[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +}; + +/* Extra bits for literal codes 257..285. */ +static const grub_uint8_t cplext[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 +}; /* 99==invalid */ + +/* Copy offsets for distance codes 0..29. */ +static const int cpdist[] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 +}; + +/* Extra bits for distance codes. */ +static const grub_uint8_t cpdext[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13 +}; + +static void +grub_png_init_huff_table (struct huff_table *ht, int cur_maxlen, + int *cur_values, int *cur_maxval, int *cur_offset) +{ + ht->values = cur_values; + ht->maxval = cur_maxval; + ht->offset = cur_offset; + ht->num_values = 0; + ht->max_length = cur_maxlen; + grub_memset (cur_maxval, 0, sizeof (int) * cur_maxlen); +} + +static void +grub_png_insert_huff_item (struct huff_table *ht, int code, int len) +{ + int i, n; + + if (len == 0) + return; + + if (len > ht->max_length) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid code length"); + return; + } + + n = 0; + for (i = len; i < ht->max_length; i++) + n += ht->maxval[i]; + + for (i = 0; i < n; i++) + ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1]; + + ht->values[ht->num_values - n] = code; + ht->num_values++; + ht->maxval[len - 1]++; +} + +static void +grub_png_build_huff_table (struct huff_table *ht) +{ + int base, ofs, i; + + base = 0; + ofs = 0; + for (i = 0; i < ht->max_length; i++) + { + base += ht->maxval[i]; + ofs += ht->maxval[i]; + + ht->maxval[i] = base; + ht->offset[i] = ofs - base; + + base <<= 1; + } +} + +static int +grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht) +{ + int code, i; + + code = 0; + for (i = 0; i < ht->max_length; i++) + { + code = (code << 1) + grub_png_get_bits (data, 1); + if (code < ht->maxval[i]) + return ht->values[code + ht->offset[i]]; + } + return 0; +} + +static grub_err_t +grub_png_init_fixed_block (struct grub_png_data *data) +{ + int i; + + grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN, + data->code_values, data->code_maxval, + data->code_offset); + + for (i = 0; i < 144; i++) + grub_png_insert_huff_item (&data->code_table, i, 8); + + for (; i < 256; i++) + grub_png_insert_huff_item (&data->code_table, i, 9); + + for (; i < 280; i++) + grub_png_insert_huff_item (&data->code_table, i, 7); + + for (; i < DEFLATE_HLIT_MAX; i++) + grub_png_insert_huff_item (&data->code_table, i, 8); + + grub_png_build_huff_table (&data->code_table); + + grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN, + data->dist_values, data->dist_maxval, + data->dist_offset); + + for (i = 0; i < DEFLATE_HDIST_MAX; i++) + grub_png_insert_huff_item (&data->dist_table, i, 5); + + grub_png_build_huff_table (&data->dist_table); + + return grub_errno; +} + +static grub_err_t +grub_png_init_dynamic_block (struct grub_png_data *data) +{ + int nl, nd, nb, i, prev; + struct huff_table cl; + int cl_values[sizeof (bitorder)]; + int cl_maxval[8]; + int cl_offset[8]; + grub_uint8_t lens[DEFLATE_HCLEN_MAX]; + + nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5); + nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5); + nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4); + + if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) || + (nb > DEFLATE_HCLEN_MAX)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: too much data"); + + grub_png_init_huff_table (&cl, 8, cl_values, cl_maxval, cl_offset); + + for (i = 0; i < nb; i++) + lens[bitorder[i]] = grub_png_get_bits (data, 3); + + for (; i < DEFLATE_HCLEN_MAX; i++) + lens[bitorder[i]] = 0; + + for (i = 0; i < DEFLATE_HCLEN_MAX; i++) + grub_png_insert_huff_item (&cl, i, lens[i]); + + grub_png_build_huff_table (&cl); + + grub_png_init_huff_table (&data->code_table, DEFLATE_HUFF_LEN, + data->code_values, data->code_maxval, + data->code_offset); + + grub_png_init_huff_table (&data->dist_table, DEFLATE_HUFF_LEN, + data->dist_values, data->dist_maxval, + data->dist_offset); + + prev = 0; + for (i = 0; i < nl + nd; i++) + { + int n, code; + struct huff_table *ht; + + if (grub_errno) + return grub_errno; + + if (i < nl) + { + ht = &data->code_table; + code = i; + } + else + { + ht = &data->dist_table; + code = i - nl; + } + + n = grub_png_get_huff_code (data, &cl); + if (n < 16) + { + grub_png_insert_huff_item (ht, code, n); + prev = n; + } + else if (n == 16) + { + int c; + + c = 3 + grub_png_get_bits (data, 2); + while (c > 0) + { + grub_png_insert_huff_item (ht, code++, prev); + i++; + c--; + } + i--; + } + else if (n == 17) + i += 3 + grub_png_get_bits (data, 3) - 1; + else + i += 11 + grub_png_get_bits (data, 7) - 1; + } + + grub_png_build_huff_table (&data->code_table); + grub_png_build_huff_table (&data->dist_table); + + return grub_errno; +} + +static grub_err_t +grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n) +{ + int row_bytes; + + if (--data->raw_bytes < 0) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown"); + + if (data->cur_colume == 0) + { + if (n >= PNG_FILTER_VALUE_LAST) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid filter value"); + + data->cur_filter = n; + } + else + *(data->cur_rgb++) = n; + + data->cur_colume++; + row_bytes = data->image_width * data->bpp; + if (data->cur_colume == row_bytes + 1) + { + grub_uint8_t *blank_line = NULL; + grub_uint8_t *cur = data->cur_rgb - row_bytes; + grub_uint8_t *left = cur; + grub_uint8_t *up; + + if (data->first_line) + { + blank_line = grub_malloc (row_bytes); + if (blank_line == NULL) + return grub_errno; + + grub_memset (blank_line, 0, row_bytes); + up = blank_line; + } + else + up = cur - row_bytes; + + switch (data->cur_filter) + { + case PNG_FILTER_VALUE_SUB: + { + int i; + + cur += data->bpp; + for (i = data->bpp; i < row_bytes; i++, cur++, left++) + *cur += *left; + + break; + } + case PNG_FILTER_VALUE_UP: + { + int i; + + for (i = 0; i < row_bytes; i++, cur++, up++) + *cur += *up; + + break; + } + case PNG_FILTER_VALUE_AVG: + { + int i; + + for (i = 0; i < data->bpp; i++, cur++, up++) + *cur += *up >> 1; + + for (; i < row_bytes; i++, cur++, up++, left++) + *cur += ((int) *up + (int) *left) >> 1; + + break; + } + case PNG_FILTER_VALUE_PAETH: + { + int i; + grub_uint8_t *upper_left = up; + + for (i = 0; i < data->bpp; i++, cur++, up++) + *cur += *up; + + for (; i < row_bytes; i++, cur++, up++, left++, upper_left++) + { + int a, b, c, pa, pb, pc; + + a = *left; + b = *up; + c = *upper_left; + + pa = b - c; + pb = a - c; + pc = pa + pb; + + if (pa < 0) + pa = -pa; + + if (pb < 0) + pb = -pb; + + if (pc < 0) + pc = -pc; + + *cur += ((pa <= pb) && (pa <= pc)) ? a : (pb <= pc) ? b : c; + } + } + } + + if (blank_line) + grub_free (blank_line); + + data->cur_colume = 0; + data->first_line = 0; + } + + return grub_errno; +} + +static grub_err_t +grub_png_read_dynamic_block (struct grub_png_data *data) +{ + while (grub_errno == 0) + { + int n; + + n = grub_png_get_huff_code (data, &data->code_table); + if (n < 256) + { + data->slide[data->wp] = n; + grub_png_output_byte (data, n); + + data->wp++; + if (data->wp >= WSIZE) + data->wp = 0; + } + else if (n == 256) + break; + else + { + int len, dist, pos; + + n -= 257; + len = cplens[n]; + if (cplext[n]) + len += grub_png_get_bits (data, cplext[n]); + + n = grub_png_get_huff_code (data, &data->dist_table); + dist = cpdist[n]; + if (cpdext[n]) + dist += grub_png_get_bits (data, cpdext[n]); + + pos = data->wp - dist; + if (pos < 0) + pos += WSIZE; + + while (len > 0) + { + data->slide[data->wp] = data->slide[pos]; + grub_png_output_byte (data, data->slide[data->wp]); + + data->wp++; + if (data->wp >= WSIZE) + data->wp = 0; + + pos++; + if (pos >= WSIZE) + pos = 0; + + len--; + } + } + } + + return grub_errno; +} + +static grub_err_t +grub_png_decode_image_data (struct grub_png_data *data) +{ + grub_uint8_t cmf, flg; + int final; + + cmf = grub_png_get_byte (data); + flg = grub_png_get_byte (data); + + if ((cmf & 0xF) != Z_DEFLATED) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: only support deflate compression method"); + + if (flg & Z_FLAG_DICT) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: dictionary not supported"); + + do + { + int block_type; + + final = grub_png_get_bits (data, 1); + block_type = grub_png_get_bits (data, 2); + + switch (block_type) + { + case INFLATE_STORED: + { + grub_uint16_t i, len; + + data->bit_count = 0; + len = grub_png_get_byte (data); + len += ((grub_uint16_t) grub_png_get_byte (data)) << 8; + + /* Skip NLEN field. */ + grub_png_get_byte (data); + grub_png_get_byte (data); + + for (i = 0; i < len; i++) + grub_png_output_byte (data, grub_png_get_byte (data)); + + break; + } + + case INFLATE_FIXED: + grub_png_init_fixed_block (data); + grub_png_read_dynamic_block (data); + break; + + case INFLATE_DYNAMIC: + grub_png_init_dynamic_block (data); + grub_png_read_dynamic_block (data); + break; + + default: + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: unknown block type"); + } + } + while ((!final) && (grub_errno == 0)); + + /* Skip adler checksum. */ + grub_png_get_dword (data); + + /* Skip crc checksum. */ + grub_png_get_dword (data); + + return grub_errno; +} + +static const grub_uint8_t png_magic[8] = + { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0x0a }; + +static void +grub_png_convert_image (struct grub_png_data *data) +{ + int i; + grub_uint8_t *d1, *d2; + + d1 = (*data->bitmap)->data; + d2 = data->image_data + 1; + + /* Only copy the upper 8 bit. */ + for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1); + i++, d1++, d2+=2) + *d1 = *d2; +} + +static grub_err_t +grub_png_decode_png (struct grub_png_data *data) +{ + grub_uint8_t magic[8]; + + if (grub_file_read (data->file, (char *) &magic[0], 8) != 8) + return grub_errno; + + if (grub_memcmp (magic, png_magic, sizeof (png_magic))) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: not a png file"); + + while (1) + { + grub_uint32_t len, type; + + len = grub_png_get_dword (data); + type = grub_png_get_dword (data); + data->next_offset = data->file->offset + len + 4; + + switch (type) + { + case PNG_CHUNK_IHDR: + grub_png_decode_image_header (data); + break; + + case PNG_CHUNK_IDAT: + data->inside_idat = 1; + data->idat_remain = len; + data->bit_count = 0; + + grub_png_decode_image_data (data); + + data->inside_idat = 0; + break; + + case PNG_CHUNK_IEND: + if (data->is_16bit) + grub_png_convert_image (data); + + return grub_errno; + + default: + grub_file_seek (data->file, data->file->offset + len + 4); + } + + if (grub_errno) + break; + + if (data->file->offset != data->next_offset) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: chunk size error"); + } + + return grub_errno; +} + +static grub_err_t +grub_video_reader_png (struct grub_video_bitmap **bitmap, + const char *filename) +{ + grub_file_t file; + struct grub_png_data *data; + + file = grub_buffile_open (filename, 0); + if (!file) + return grub_errno; + + data = grub_malloc (sizeof (*data)); + if (data != NULL) + { + grub_memset (data, 0, sizeof (*data)); + data->file = file; + data->bitmap = bitmap; + + grub_png_decode_png (data); + + grub_free (data->image_data); + grub_free (data); + } + + if (grub_errno != GRUB_ERR_NONE) + { + grub_video_bitmap_destroy (*bitmap); + *bitmap = 0; + } + + grub_file_close (file); + return grub_errno; +} + +#if defined(PNG_DEBUG) +static grub_err_t +grub_cmd_pngtest (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_video_bitmap *bitmap = 0; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_video_reader_png (&bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_video_bitmap_destroy (bitmap); + + return GRUB_ERR_NONE; +} +#endif + +static struct grub_video_bitmap_reader png_reader = { + .extension = ".png", + .reader = grub_video_reader_png, + .next = 0 +}; + +GRUB_MOD_INIT (video_reader_png) +{ + grub_video_bitmap_reader_register (&png_reader); +#if defined(PNG_DEBUG) + grub_register_command ("pngtest", grub_cmd_pngtest, + GRUB_COMMAND_FLAG_BOTH, "pngtest FILE", + "Tests loading of PNG bitmap.", 0); +#endif +} + +GRUB_MOD_FINI (video_reader_png) +{ +#if defined(PNG_DEBUG) + grub_unregister_command ("pngtest"); +#endif + grub_video_bitmap_reader_unregister (&png_reader); +} diff --git a/video/readers/tga.c b/video/readers/tga.c new file mode 100644 index 0000000..de56008 --- /dev/null +++ b/video/readers/tga.c @@ -0,0 +1,495 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Uncomment following define to enable TGA debug. */ +//#define TGA_DEBUG + +#if defined(TGA_DEBUG) +#define dump_int_field(x) grub_printf( #x " = %d (0x%04x)\n", x, x); +#endif + +enum +{ + GRUB_TGA_IMAGE_TYPE_NONE = 0, + GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_INDEXCOLOR = 1, + GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR = 2, + GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_BLACK_AND_WHITE = 3, + GRUB_TGA_IMAGE_TYPE_RLE_INDEXCOLOR = 9, + GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR = 10, + GRUB_TGA_IMAGE_TYPE_RLE_BLACK_AND_WHITE = 11, +}; + +enum +{ + GRUB_TGA_COLOR_MAP_TYPE_NONE = 0, + GRUB_TGA_COLOR_MAP_TYPE_INCLUDED = 1 +}; + +enum +{ + GRUB_TGA_IMAGE_ORIGIN_RIGHT = 0x10, + GRUB_TGA_IMAGE_ORIGIN_TOP = 0x20 +}; + +struct grub_tga_header +{ + grub_uint8_t id_length; + grub_uint8_t color_map_type; + grub_uint8_t image_type; + + /* Color Map Specification. */ + grub_uint16_t color_map_first_index; + grub_uint16_t color_map_length; + grub_uint8_t color_map_bpp; + + /* Image Specification. */ + grub_uint16_t image_x_origin; + grub_uint16_t image_y_origin; + grub_uint16_t image_width; + grub_uint16_t image_height; + grub_uint8_t image_bpp; + grub_uint8_t image_descriptor; +} __attribute__ ((packed)); + +static grub_err_t +tga_load_truecolor_rle_R8G8B8 (struct grub_video_bitmap *bitmap, + struct grub_tga_header *header, + grub_file_t file) +{ + unsigned int x; + unsigned int y; + grub_uint8_t type; + grub_uint8_t *ptr; + grub_uint8_t tmp[4]; /* Size should be max_bpp / 8. */ + grub_uint8_t bytes_per_pixel; + + bytes_per_pixel = header->image_bpp / 8; + + for (y = 0; y < header->image_height; y++) + { + ptr = bitmap->data; + if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) + ptr += y * bitmap->mode_info.pitch; + else + ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch; + + for (x = 0; x < header->image_width;) + { + if (grub_file_read (file, (char *)&type, sizeof (type)) != sizeof(type)) + return grub_errno; + + if (type & 0x80) + { + /* RLE-encoded packet. */ + type &= 0x7f; + type++; + + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + while (type) + { + if (x < header->image_width) + { + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + ptr += 3; + } + + type--; + x++; + } + } + else + { + /* RAW-encoded packet. */ + type++; + + while (type) + { + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + if (x < header->image_width) + { + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + ptr += 3; + } + + type--; + x++; + } + } + } + } + return GRUB_ERR_NONE; +} + +static grub_err_t +tga_load_truecolor_rle_R8G8B8A8 (struct grub_video_bitmap *bitmap, + struct grub_tga_header *header, + grub_file_t file) +{ + unsigned int x; + unsigned int y; + grub_uint8_t type; + grub_uint8_t *ptr; + grub_uint8_t tmp[4]; /* Size should be max_bpp / 8. */ + grub_uint8_t bytes_per_pixel; + + bytes_per_pixel = header->image_bpp / 8; + + for (y = 0; y < header->image_height; y++) + { + ptr = bitmap->data; + if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) + ptr += y * bitmap->mode_info.pitch; + else + ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch; + + for (x = 0; x < header->image_width;) + { + if (grub_file_read (file, (char *)&type, sizeof (type)) != sizeof(type)) + return grub_errno; + + if (type & 0x80) + { + /* RLE-encoded packet. */ + type &= 0x7f; + type++; + + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + while (type) + { + if (x < header->image_width) + { + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + ptr[3] = tmp[3]; + ptr += 4; + } + + type--; + x++; + } + } + else + { + /* RAW-encoded packet. */ + type++; + + while (type) + { + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + if (x < header->image_width) + { + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + ptr[3] = tmp[3]; + ptr += 4; + } + + type--; + x++; + } + } + } + } + return GRUB_ERR_NONE; +} + +static grub_err_t +tga_load_truecolor_R8G8B8 (struct grub_video_bitmap *bitmap, + struct grub_tga_header *header, + grub_file_t file) +{ + unsigned int x; + unsigned int y; + grub_uint8_t *ptr; + grub_uint8_t tmp[4]; /* Size should be max_bpp / 8. */ + grub_uint8_t bytes_per_pixel; + + bytes_per_pixel = header->image_bpp / 8; + + for (y = 0; y < header->image_height; y++) + { + ptr = bitmap->data; + if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) + ptr += y * bitmap->mode_info.pitch; + else + ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch; + + for (x = 0; x < header->image_width; x++) + { + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + + ptr += 3; + } + } + return GRUB_ERR_NONE; +} + +static grub_err_t +tga_load_truecolor_R8G8B8A8 (struct grub_video_bitmap *bitmap, + struct grub_tga_header *header, + grub_file_t file) +{ + unsigned int x; + unsigned int y; + grub_uint8_t *ptr; + grub_uint8_t tmp[4]; /* Size should be max_bpp / 8. */ + grub_uint8_t bytes_per_pixel; + + bytes_per_pixel = header->image_bpp / 8; + + for (y = 0; y < header->image_height; y++) + { + ptr = bitmap->data; + if ((header->image_descriptor & GRUB_TGA_IMAGE_ORIGIN_TOP) != 0) + ptr += y * bitmap->mode_info.pitch; + else + ptr += (header->image_height - 1 - y) * bitmap->mode_info.pitch; + + for (x = 0; x < header->image_width; x++) + { + if (grub_file_read (file, (char *)&tmp[0], bytes_per_pixel) + != bytes_per_pixel) + return grub_errno; + + ptr[0] = tmp[2]; + ptr[1] = tmp[1]; + ptr[2] = tmp[0]; + ptr[3] = tmp[3]; + + ptr += 4; + } + } + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_reader_tga (struct grub_video_bitmap **bitmap, + const char *filename) +{ + grub_file_t file; + grub_ssize_t pos; + struct grub_tga_header header; + int has_alpha; + + file = grub_buffile_open (filename, 0); + if (! file) + return grub_errno; + + /* TGA Specification states that we SHOULD start by reading + ID from end of file, but we really don't care about that as we are + not going to support developer area & extensions at this point. */ + + /* Read TGA header from beginning of file. */ + if (grub_file_read (file, (char*)&header, sizeof (header)) + != sizeof (header)) + { + grub_file_close (file); + return grub_errno; + } + + /* Skip ID field. */ + pos = grub_file_tell (file); + pos += header.id_length; + grub_file_seek (file, pos); + if (grub_errno != GRUB_ERR_NONE) + { + grub_file_close (file); + return grub_errno; + } + +#if defined(TGA_DEBUG) + grub_printf("tga: header\n"); + dump_int_field(header.id_length); + dump_int_field(header.color_map_type); + dump_int_field(header.image_type); + dump_int_field(header.color_map_first_index); + dump_int_field(header.color_map_length); + dump_int_field(header.color_map_bpp); + dump_int_field(header.image_x_origin); + dump_int_field(header.image_y_origin); + dump_int_field(header.image_width); + dump_int_field(header.image_height); + dump_int_field(header.image_bpp); + dump_int_field(header.image_descriptor); +#endif + + /* Check that bitmap encoding is supported. */ + switch (header.image_type) + { + case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: + case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: + break; + + default: + grub_file_close (file); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "Unsupported bitmap format (unknown encoding)."); + } + + /* Check that bitmap depth is supported. */ + switch (header.image_bpp) + { + case 24: + has_alpha = 0; + break; + + case 32: + has_alpha = 1; + break; + + default: + grub_file_close (file); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "Unsupported bitmap format (bpp=%d).", + header.image_bpp); + } + + /* Allocate bitmap. If there is alpha information store it too. */ + if (has_alpha) + { + grub_video_bitmap_create (bitmap, header.image_width, + header.image_height, + GRUB_VIDEO_BLIT_FORMAT_RGBA_8888); + if (grub_errno != GRUB_ERR_NONE) + { + grub_file_close (file); + return grub_errno; + } + + /* Load bitmap data. */ + switch (header.image_type) + { + case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: + tga_load_truecolor_R8G8B8A8 (*bitmap, &header, file); + break; + + case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: + tga_load_truecolor_rle_R8G8B8A8 (*bitmap, &header, file); + break; + } + } + else + { + grub_video_bitmap_create (bitmap, header.image_width, + header.image_height, + GRUB_VIDEO_BLIT_FORMAT_RGB_888); + if (grub_errno != GRUB_ERR_NONE) + { + grub_file_close (file); + return grub_errno; + } + + /* Load bitmap data. */ + switch (header.image_type) + { + case GRUB_TGA_IMAGE_TYPE_UNCOMPRESSED_TRUECOLOR: + tga_load_truecolor_R8G8B8 (*bitmap, &header, file); + break; + + case GRUB_TGA_IMAGE_TYPE_RLE_TRUECOLOR: + tga_load_truecolor_rle_R8G8B8 (*bitmap, &header, file); + break; + } + } + + /* If there was a loading problem, destroy bitmap. */ + if (grub_errno != GRUB_ERR_NONE) + { + grub_video_bitmap_destroy (*bitmap); + *bitmap = 0; + } + + grub_file_close (file); + return grub_errno; +} + +#if defined(TGA_DEBUG) +static grub_err_t +grub_cmd_tgatest (struct grub_arg_list *state __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_video_bitmap *bitmap = 0; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + + grub_video_reader_tga (&bitmap, args[0]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_video_bitmap_destroy (bitmap); + + return GRUB_ERR_NONE; +} +#endif + +static struct grub_video_bitmap_reader tga_reader = { + .extension = ".tga", + .reader = grub_video_reader_tga, + .next = 0 +}; + +GRUB_MOD_INIT(video_reader_tga) +{ + grub_video_bitmap_reader_register (&tga_reader); +#if defined(TGA_DEBUG) + grub_register_command ("tgatest", grub_cmd_tgatest, GRUB_COMMAND_FLAG_BOTH, + "tgatest FILE", "Tests loading of TGA bitmap.", 0); +#endif +} + +GRUB_MOD_FINI(video_reader_tga) +{ +#if defined(TGA_DEBUG) + grub_unregister_command ("tgatest"); +#endif + grub_video_bitmap_reader_unregister (&tga_reader); +} diff --git a/video/video.c b/video/video.c new file mode 100644 index 0000000..49e6cb9 --- /dev/null +++ b/video/video.c @@ -0,0 +1,443 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +/* The list of video adapters registered to system. */ +static grub_video_adapter_t grub_video_adapter_list; + +/* Active video adapter. */ +static grub_video_adapter_t grub_video_adapter_active; + +/* Register video driver. */ +void +grub_video_register (grub_video_adapter_t adapter) +{ + adapter->next = grub_video_adapter_list; + grub_video_adapter_list = adapter; +} + +/* Unregister video driver. */ +void +grub_video_unregister (grub_video_adapter_t adapter) +{ + grub_video_adapter_t *p, q; + + for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next) + if (q == adapter) + { + *p = q->next; + break; + } +} + +/* Iterate thru all registered video drivers. */ +void +grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)) +{ + grub_video_adapter_t p; + + for (p = grub_video_adapter_list; p; p = p->next) + if (hook (p)) + break; +} + +/* Setup specified video mode. */ +grub_err_t +grub_video_setup (unsigned int width, unsigned int height, + unsigned int mode_type) +{ + grub_video_adapter_t p; + + /* De-activate last set video adapter. */ + if (grub_video_adapter_active) + { + /* Finalize adapter. */ + grub_video_adapter_active->fini (); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + /* Mark active adapter as not set. */ + grub_video_adapter_active = 0; + } + + /* Loop thru all possible video adapter trying to find requested mode. */ + for (p = grub_video_adapter_list; p; p = p->next) + { + /* Try to initialize adapter, if it fails, skip to next adapter. */ + p->init (); + if (grub_errno != GRUB_ERR_NONE) + { + grub_errno = GRUB_ERR_NONE; + continue; + } + + /* Try to initialize video mode. */ + p->setup (width, height, mode_type); + if (grub_errno == GRUB_ERR_NONE) + { + /* Valid mode found from adapter, and it has been activated. + Specify it as active adapter. */ + grub_video_adapter_active = p; + return GRUB_ERR_NONE; + } + else + grub_errno = GRUB_ERR_NONE; + + /* No valid mode found in this adapter, finalize adapter. */ + p->fini (); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + } + + /* We couldn't find suitable adapter for specified mode. */ + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "Can't locate valid adapter for mode"); +} + +/* Restore back to initial mode (where applicable). */ +grub_err_t +grub_video_restore (void) +{ + if (grub_video_adapter_active) + { + grub_video_adapter_active->fini (); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + grub_video_adapter_active = 0; + } + return GRUB_ERR_NONE; +} + +/* Get information about active video mode. */ +grub_err_t +grub_video_get_info (struct grub_video_mode_info *mode_info) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + /* If mode_info is NULL just report that video adapter is active. */ + if (! mode_info) + { + grub_errno = GRUB_ERR_NONE; + return grub_errno; + } + + return grub_video_adapter_active->get_info (mode_info); +} + +/* Determine optimized blitting formation for specified video mode info. */ +enum grub_video_blit_format +grub_video_get_blit_format (struct grub_video_mode_info *mode_info) +{ + /* Check if we have any known 32 bit modes. */ + if (mode_info->bpp == 32) + { + if ((mode_info->red_mask_size == 8) + && (mode_info->red_field_pos == 16) + && (mode_info->green_mask_size == 8) + && (mode_info->green_field_pos == 8) + && (mode_info->blue_mask_size == 8) + && (mode_info->blue_field_pos == 0)) + { + return GRUB_VIDEO_BLIT_FORMAT_BGRA_8888; + } + else if ((mode_info->red_mask_size == 8) + && (mode_info->red_field_pos == 0) + && (mode_info->green_mask_size == 8) + && (mode_info->green_field_pos == 8) + && (mode_info->blue_mask_size == 8) + && (mode_info->blue_field_pos == 16)) + { + return GRUB_VIDEO_BLIT_FORMAT_RGBA_8888; + } + } + /* Check if we have any known 24 bit modes. */ + else if (mode_info->bpp == 24) + { + if ((mode_info->red_mask_size == 8) + && (mode_info->red_field_pos == 16) + && (mode_info->green_mask_size == 8) + && (mode_info->green_field_pos == 8) + && (mode_info->blue_mask_size == 8) + && (mode_info->blue_field_pos == 0)) + { + return GRUB_VIDEO_BLIT_FORMAT_BGR_888; + } + else if ((mode_info->red_mask_size == 8) + && (mode_info->red_field_pos == 0) + && (mode_info->green_mask_size == 8) + && (mode_info->green_field_pos == 8) + && (mode_info->blue_mask_size == 8) + && (mode_info->blue_field_pos == 16)) + { + return GRUB_VIDEO_BLIT_FORMAT_RGB_888; + } + } + /* Check if we have any known 16 bit modes. */ + else if (mode_info->bpp == 16) + { + if ((mode_info->red_mask_size == 5) + && (mode_info->red_field_pos == 11) + && (mode_info->green_mask_size == 6) + && (mode_info->green_field_pos == 5) + && (mode_info->blue_mask_size == 5) + && (mode_info->blue_field_pos == 0)) + { + return GRUB_VIDEO_BLIT_FORMAT_BGR_565; + } + else if ((mode_info->red_mask_size == 5) + && (mode_info->red_field_pos == 0) + && (mode_info->green_mask_size == 6) + && (mode_info->green_field_pos == 5) + && (mode_info->blue_mask_size == 5) + && (mode_info->blue_field_pos == 11)) + { + return GRUB_VIDEO_BLIT_FORMAT_RGB_565; + } + } + + /* Backup route. Unknown format. */ + + /* If there are more than 8 bits per color, assume RGB(A) mode. */ + if (mode_info->bpp > 8) + { + if (mode_info->reserved_mask_size > 0) + { + return GRUB_VIDEO_BLIT_FORMAT_RGBA; + } + else + { + return GRUB_VIDEO_BLIT_FORMAT_RGB; + } + } + + /* Assume as indexcolor mode. */ + return GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR; +} + +/* Set new indexed color palette entries. */ +grub_err_t +grub_video_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->set_palette (start, count, palette_data); +} + +/* Get indexed color palette entries. */ +grub_err_t +grub_video_get_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->get_palette (start, count, palette_data); +} + +/* Set viewport dimensions. */ +grub_err_t +grub_video_set_viewport (unsigned int x, unsigned int y, + unsigned int width, unsigned int height) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->set_viewport (x, y, width, height); +} + +/* Get viewport dimensions. */ +grub_err_t +grub_video_get_viewport (unsigned int *x, unsigned int *y, + unsigned int *width, unsigned int *height) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->get_viewport (x, y, width, height); +} + +/* Map color name to adapter specific color. */ +grub_video_color_t +grub_video_map_color (grub_uint32_t color_name) +{ + if (! grub_video_adapter_active) + return 0; + + return grub_video_adapter_active->map_color (color_name); +} + +/* Map RGB value to adapter specific color. */ +grub_video_color_t +grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue) +{ + if (! grub_video_adapter_active) + return 0; + + return grub_video_adapter_active->map_rgb (red, green, blue); +} + +/* Map RGBA value to adapter specific color. */ +grub_video_color_t +grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, grub_uint8_t blue, + grub_uint8_t alpha) +{ + if (! grub_video_adapter_active) + return 0; + + return grub_video_adapter_active->map_rgba (red, green, blue, alpha); +} + +/* Unmap video color back to RGBA components. */ +grub_err_t +grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, + grub_uint8_t *green, grub_uint8_t *blue, + grub_uint8_t *alpha) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->unmap_color (color, + red, + green, + blue, + alpha); +} + +/* Fill rectangle using specified color. */ +grub_err_t +grub_video_fill_rect (grub_video_color_t color, int x, int y, + unsigned int width, unsigned int height) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->fill_rect (color, x, y, width, height); +} + +/* Blit bitmap to screen. */ +grub_err_t +grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y, + offset_x, offset_y, + width, height); +} + +/* Blit render target to active render target. */ +grub_err_t +grub_video_blit_render_target (struct grub_video_render_target *target, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->blit_render_target (target, oper, x, y, + offset_x, offset_y, + width, height); +} + +/* Scroll viewport and fill new areas with specified color. */ +grub_err_t +grub_video_scroll (grub_video_color_t color, int dx, int dy) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->scroll (color, dx, dy); +} + +/* Swap buffers (swap active render target). */ +grub_err_t +grub_video_swap_buffers (void) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->swap_buffers (); +} + +/* Create new render target. */ +grub_err_t +grub_video_create_render_target (struct grub_video_render_target **result, + unsigned int width, unsigned int height, + unsigned int mode_type) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->create_render_target (result, + width, height, + mode_type); +} + +/* Delete render target. */ +grub_err_t +grub_video_delete_render_target (struct grub_video_render_target *target) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->delete_render_target (target); +} + +/* Set active render target. */ +grub_err_t +grub_video_set_active_render_target (struct grub_video_render_target *target) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->set_active_render_target (target); +} + +/* Get active render target. */ +grub_err_t +grub_video_get_active_render_target (struct grub_video_render_target **target) +{ + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + + return grub_video_adapter_active->get_active_render_target (target); +} + +/* Initialize Video API module. */ +GRUB_MOD_INIT(video_video) +{ + grub_video_adapter_active = 0; + grub_video_adapter_list = 0; +} + +/* Finalize Video API module. */ +GRUB_MOD_FINI(video_video) +{ +} -- 2.39.5