diff --git a/ChangeLog b/ChangeLog index 95a834e6c..fcfb850bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +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 endianess 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. diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk index faef6da34..87e5c151a 100644 --- a/conf/i386-pc.mk +++ b/conf/i386-pc.mk @@ -311,11 +311,11 @@ grub_mkimage_LDFLAGS = -llzo grub_setup_SOURCES = util/i386/pc/grub-setup.c util/i386/pc/biosdisk.c \ util/misc.c util/i386/pc/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c disk/i386/pc/partition.c fs/fat.c fs/ext2.c \ - fs/ufs.c fs/minix.c fs/hfs.c kern/file.c kern/fs.c kern/env.c -CLEANFILES += grub-setup grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-disk_i386_pc_partition.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o -MOSTLYCLEANFILES += grub_setup-util_i386_pc_grub_setup.d grub_setup-util_i386_pc_biosdisk.d grub_setup-util_misc.d grub_setup-util_i386_pc_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-disk_i386_pc_partition.d grub_setup-fs_fat.d grub_setup-fs_ext2.d grub_setup-fs_ufs.d grub_setup-fs_minix.d grub_setup-fs_hfs.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d + fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c kern/file.c kern/fs.c kern/env.c +CLEANFILES += grub-setup grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-disk_i386_pc_partition.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o +MOSTLYCLEANFILES += grub_setup-util_i386_pc_grub_setup.d grub_setup-util_i386_pc_biosdisk.d grub_setup-util_misc.d grub_setup-util_i386_pc_getroot.d grub_setup-kern_device.d grub_setup-kern_disk.d grub_setup-kern_err.d grub_setup-kern_misc.d grub_setup-disk_i386_pc_partition.d grub_setup-fs_fat.d grub_setup-fs_ext2.d grub_setup-fs_ufs.d grub_setup-fs_minix.d grub_setup-fs_hfs.d grub_setup-fs_jfs.d grub_setup-kern_file.d grub_setup-kern_fs.d grub_setup-kern_env.d -grub-setup: grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-disk_i386_pc_partition.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o +grub-setup: grub_setup-util_i386_pc_grub_setup.o grub_setup-util_i386_pc_biosdisk.o grub_setup-util_misc.o grub_setup-util_i386_pc_getroot.o grub_setup-kern_device.o grub_setup-kern_disk.o grub_setup-kern_err.o grub_setup-kern_misc.o grub_setup-disk_i386_pc_partition.o grub_setup-fs_fat.o grub_setup-fs_ext2.o grub_setup-fs_ufs.o grub_setup-fs_minix.o grub_setup-fs_hfs.o grub_setup-fs_jfs.o grub_setup-kern_file.o grub_setup-kern_fs.o grub_setup-kern_env.o $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grub_setup_LDFLAGS) grub_setup-util_i386_pc_grub_setup.o: util/i386/pc/grub-setup.c @@ -430,6 +430,14 @@ grub_setup-fs_hfs.d: fs/hfs.c -include grub_setup-fs_hfs.d +grub_setup-fs_jfs.o: fs/jfs.c + $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -c -o $@ $< + +grub_setup-fs_jfs.d: fs/jfs.c + set -e; $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -M $< | sed 's,jfs\.o[ :]*,grub_setup-fs_jfs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grub_setup-fs_jfs.d + grub_setup-kern_file.o: kern/file.c $(BUILD_CC) -Ikern -I$(srcdir)/kern $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_setup_CFLAGS) -c -o $@ $< @@ -461,13 +469,13 @@ grub_emu_SOURCES = kern/main.c kern/device.c \ kern/misc.c kern/loader.c kern/rescue.c kern/term.c \ disk/i386/pc/partition.c kern/env.c commands/ls.c \ commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c \ - util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ + util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c\ normal/cmdline.c normal/command.c normal/main.c normal/menu.c normal/arg.c \ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c -CLEANFILES += grub-emu grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_i386_pc_partition.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o -MOSTLYCLEANFILES += grub_emu-kern_main.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_err.d grub_emu-kern_misc.d grub_emu-kern_loader.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-disk_i386_pc_partition.d grub_emu-kern_env.d grub_emu-commands_ls.d grub_emu-commands_terminal.d grub_emu-commands_boot.d grub_emu-commands_cmp.d grub_emu-commands_cat.d grub_emu-util_i386_pc_biosdisk.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_ufs.d grub_emu-fs_minix.d grub_emu-fs_hfs.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_arg.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_getroot.d +CLEANFILES += grub-emu grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_i386_pc_partition.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-fs_jfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o +MOSTLYCLEANFILES += grub_emu-kern_main.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_err.d grub_emu-kern_misc.d grub_emu-kern_loader.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-disk_i386_pc_partition.d grub_emu-kern_env.d grub_emu-commands_ls.d grub_emu-commands_terminal.d grub_emu-commands_boot.d grub_emu-commands_cmp.d grub_emu-commands_cat.d grub_emu-util_i386_pc_biosdisk.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_ufs.d grub_emu-fs_minix.d grub_emu-fs_hfs.d grub_emu-fs_jfs.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_arg.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_getroot.d -grub-emu: grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_i386_pc_partition.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o +grub-emu: grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_i386_pc_partition.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-fs_jfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grub_emu_LDFLAGS) grub_emu-kern_main.o: kern/main.c @@ -662,6 +670,14 @@ grub_emu-fs_hfs.d: fs/hfs.c -include grub_emu-fs_hfs.d +grub_emu-fs_jfs.o: fs/jfs.c + $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $< + +grub_emu-fs_jfs.d: fs/jfs.c + set -e; $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -M $< | sed 's,jfs\.o[ :]*,grub_emu-fs_jfs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grub_emu-fs_jfs.d + grub_emu-normal_cmdline.o: normal/cmdline.c $(BUILD_CC) -Inormal -I$(srcdir)/normal $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $< @@ -755,7 +771,7 @@ genmoddep-util_genmoddep.d: util/genmoddep.c # Modules. pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod \ - hfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ + hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ boot.mod cmp.mod cat.mod terminal.mod # For _chain.mod. @@ -992,6 +1008,45 @@ hfs_mod-fs_hfs.d: fs/hfs.c hfs_mod_CFLAGS = $(COMMON_CFLAGS) +# 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 def-jfs.lst und-jfs.lst +MOSTLYCLEANFILES += jfs_mod-fs_jfs.d +DEFSYMFILES += def-jfs.lst +UNDSYMFILES += und-jfs.lst + +jfs.mod: pre-jfs.o mod-jfs.o + -rm -f $@ + $(LD) -r -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-jfs.o: jfs_mod-fs_jfs.o + -rm -f $@ + $(LD) -r -o $@ $^ + +mod-jfs.o: mod-jfs.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(jfs_mod_CFLAGS) -c -o $@ $< + +mod-jfs.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'jfs' $< > $@ || (rm -f $@; exit 1) + +def-jfs.lst: pre-jfs.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 jfs/' > $@ + +und-jfs.lst: pre-jfs.o + echo 'jfs' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +jfs_mod-fs_jfs.o: fs/jfs.c + $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) $(jfs_mod_CFLAGS) -c -o $@ $< + +jfs_mod-fs_jfs.d: fs/jfs.c + set -e; $(CC) -Ifs -I$(srcdir)/fs $(CPPFLAGS) $(CFLAGS) $(jfs_mod_CFLAGS) -M $< | sed 's,jfs\.o[ :]*,jfs_mod-fs_jfs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include jfs_mod-fs_jfs.d + +jfs_mod_CFLAGS = $(COMMON_CFLAGS) + # 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 def-_linux.lst und-_linux.lst diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2daa5d65f..f06cc0ff3 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -61,7 +61,7 @@ grub_mkimage_LDFLAGS = -llzo grub_setup_SOURCES = util/i386/pc/grub-setup.c util/i386/pc/biosdisk.c \ util/misc.c util/i386/pc/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c disk/i386/pc/partition.c fs/fat.c fs/ext2.c \ - fs/ufs.c fs/minix.c fs/hfs.c kern/file.c kern/fs.c kern/env.c + fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c kern/file.c kern/fs.c kern/env.c # For grub grub_emu_SOURCES = kern/main.c kern/device.c \ @@ -69,7 +69,7 @@ grub_emu_SOURCES = kern/main.c kern/device.c \ kern/misc.c kern/loader.c kern/rescue.c kern/term.c \ disk/i386/pc/partition.c kern/env.c commands/ls.c \ commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c \ - util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ + util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c fs/jfs.c\ normal/cmdline.c normal/command.c normal/main.c normal/menu.c normal/arg.c \ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c grub_emu_LDFLAGS = -lncurses @@ -79,7 +79,7 @@ genmoddep_SOURCES = util/genmoddep.c # Modules. pkgdata_MODULES = _chain.mod _linux.mod fat.mod ufs.mod ext2.mod minix.mod \ - hfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ + hfs.mod jfs.mod normal.mod hello.mod vga.mod font.mod _multiboot.mod ls.mod \ boot.mod cmp.mod cat.mod terminal.mod # For _chain.mod. @@ -106,6 +106,10 @@ minix_mod_CFLAGS = $(COMMON_CFLAGS) hfs_mod_SOURCES = fs/hfs.c hfs_mod_CFLAGS = $(COMMON_CFLAGS) +# For jfs.mod. +jfs_mod_SOURCES = fs/jfs.c +jfs_mod_CFLAGS = $(COMMON_CFLAGS) + # For _linux.mod. _linux_mod_SOURCES = loader/i386/pc/linux.c _linux_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/powerpc-ieee1275.mk b/conf/powerpc-ieee1275.mk index c49dba07e..92ed7ee5d 100644 --- a/conf/powerpc-ieee1275.mk +++ b/conf/powerpc-ieee1275.mk @@ -26,15 +26,15 @@ grub_emu_SOURCES = kern/main.c kern/device.c \ kern/misc.c kern/loader.c kern/rescue.c kern/term.c \ disk/powerpc/ieee1275/partition.c \ util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ - normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ + fs/jfs.c normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ normal/arg.c \ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c \ kern/env.c commands/ls.c \ commands/terminal.c commands/boot.c commands/cmp.c commands/cat.c -CLEANFILES += grub-emu grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_powerpc_ieee1275_partition.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o -MOSTLYCLEANFILES += grub_emu-kern_main.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_err.d grub_emu-kern_misc.d grub_emu-kern_loader.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-disk_powerpc_ieee1275_partition.d grub_emu-util_i386_pc_biosdisk.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_ufs.d grub_emu-fs_minix.d grub_emu-fs_hfs.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_arg.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_getroot.d grub_emu-kern_env.d grub_emu-commands_ls.d grub_emu-commands_terminal.d grub_emu-commands_boot.d grub_emu-commands_cmp.d grub_emu-commands_cat.d +CLEANFILES += grub-emu grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_powerpc_ieee1275_partition.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-fs_jfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o +MOSTLYCLEANFILES += grub_emu-kern_main.d grub_emu-kern_device.d grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_err.d grub_emu-kern_misc.d grub_emu-kern_loader.d grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-disk_powerpc_ieee1275_partition.d grub_emu-util_i386_pc_biosdisk.d grub_emu-fs_fat.d grub_emu-fs_ext2.d grub_emu-fs_ufs.d grub_emu-fs_minix.d grub_emu-fs_hfs.d grub_emu-fs_jfs.d grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_arg.d grub_emu-util_console.d grub_emu-util_grub_emu.d grub_emu-util_misc.d grub_emu-util_i386_pc_getroot.d grub_emu-kern_env.d grub_emu-commands_ls.d grub_emu-commands_terminal.d grub_emu-commands_boot.d grub_emu-commands_cmp.d grub_emu-commands_cat.d -grub-emu: grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_powerpc_ieee1275_partition.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o +grub-emu: grub_emu-kern_main.o grub_emu-kern_device.o grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_err.o grub_emu-kern_misc.o grub_emu-kern_loader.o grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-disk_powerpc_ieee1275_partition.o grub_emu-util_i386_pc_biosdisk.o grub_emu-fs_fat.o grub_emu-fs_ext2.o grub_emu-fs_ufs.o grub_emu-fs_minix.o grub_emu-fs_hfs.o grub_emu-fs_jfs.o grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_arg.o grub_emu-util_console.o grub_emu-util_grub_emu.o grub_emu-util_misc.o grub_emu-util_i386_pc_getroot.o grub_emu-kern_env.o grub_emu-commands_ls.o grub_emu-commands_terminal.o grub_emu-commands_boot.o grub_emu-commands_cmp.o grub_emu-commands_cat.o $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grub_emu_LDFLAGS) grub_emu-kern_main.o: kern/main.c @@ -181,6 +181,14 @@ grub_emu-fs_hfs.d: fs/hfs.c -include grub_emu-fs_hfs.d +grub_emu-fs_jfs.o: fs/jfs.c + $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $< + +grub_emu-fs_jfs.d: fs/jfs.c + set -e; $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -M $< | sed 's,jfs\.o[ :]*,grub_emu-fs_jfs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grub_emu-fs_jfs.d + grub_emu-normal_cmdline.o: normal/cmdline.c $(BUILD_CC) -Inormal -I$(srcdir)/normal $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $< @@ -309,14 +317,14 @@ grubof_SOURCES = boot/powerpc/ieee1275/cmain.c boot/powerpc/ieee1275/ieee1275.c kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ kern/powerpc/ieee1275/init.c term/powerpc/ieee1275/ofconsole.c \ kern/powerpc/ieee1275/openfw.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ - normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ + fs/jfs.c normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ disk/powerpc/ieee1275/ofdisk.c disk/powerpc/ieee1275/partition.c \ kern/env.c normal/arg.c loader/powerpc/ieee1275/linux.c \ loader/powerpc/ieee1275/linux_normal.c commands/boot.c -CLEANFILES += grubof grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-boot_powerpc_ieee1275_crt0.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-disk_powerpc_ieee1275_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o -MOSTLYCLEANFILES += grubof-boot_powerpc_ieee1275_cmain.d grubof-boot_powerpc_ieee1275_ieee1275.d grubof-boot_powerpc_ieee1275_crt0.d grubof-kern_main.d grubof-kern_device.d grubof-kern_disk.d grubof-kern_dl.d grubof-kern_file.d grubof-kern_fs.d grubof-kern_err.d grubof-kern_misc.d grubof-kern_mm.d grubof-kern_loader.d grubof-kern_rescue.d grubof-kern_term.d grubof-kern_powerpc_ieee1275_init.d grubof-term_powerpc_ieee1275_ofconsole.d grubof-kern_powerpc_ieee1275_openfw.d grubof-fs_ext2.d grubof-fs_ufs.d grubof-fs_minix.d grubof-fs_hfs.d grubof-normal_cmdline.d grubof-normal_command.d grubof-normal_main.d grubof-normal_menu.d grubof-disk_powerpc_ieee1275_ofdisk.d grubof-disk_powerpc_ieee1275_partition.d grubof-kern_env.d grubof-normal_arg.d grubof-loader_powerpc_ieee1275_linux.d grubof-loader_powerpc_ieee1275_linux_normal.d grubof-commands_boot.d +CLEANFILES += grubof grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-boot_powerpc_ieee1275_crt0.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-disk_powerpc_ieee1275_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o +MOSTLYCLEANFILES += grubof-boot_powerpc_ieee1275_cmain.d grubof-boot_powerpc_ieee1275_ieee1275.d grubof-boot_powerpc_ieee1275_crt0.d grubof-kern_main.d grubof-kern_device.d grubof-kern_disk.d grubof-kern_dl.d grubof-kern_file.d grubof-kern_fs.d grubof-kern_err.d grubof-kern_misc.d grubof-kern_mm.d grubof-kern_loader.d grubof-kern_rescue.d grubof-kern_term.d grubof-kern_powerpc_ieee1275_init.d grubof-term_powerpc_ieee1275_ofconsole.d grubof-kern_powerpc_ieee1275_openfw.d grubof-fs_ext2.d grubof-fs_ufs.d grubof-fs_minix.d grubof-fs_hfs.d grubof-fs_jfs.d grubof-normal_cmdline.d grubof-normal_command.d grubof-normal_main.d grubof-normal_menu.d grubof-disk_powerpc_ieee1275_ofdisk.d grubof-disk_powerpc_ieee1275_partition.d grubof-kern_env.d grubof-normal_arg.d grubof-loader_powerpc_ieee1275_linux.d grubof-loader_powerpc_ieee1275_linux_normal.d grubof-commands_boot.d -grubof: grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-boot_powerpc_ieee1275_crt0.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-disk_powerpc_ieee1275_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o +grubof: grubof-boot_powerpc_ieee1275_cmain.o grubof-boot_powerpc_ieee1275_ieee1275.o grubof-boot_powerpc_ieee1275_crt0.o grubof-kern_main.o grubof-kern_device.o grubof-kern_disk.o grubof-kern_dl.o grubof-kern_file.o grubof-kern_fs.o grubof-kern_err.o grubof-kern_misc.o grubof-kern_mm.o grubof-kern_loader.o grubof-kern_rescue.o grubof-kern_term.o grubof-kern_powerpc_ieee1275_init.o grubof-term_powerpc_ieee1275_ofconsole.o grubof-kern_powerpc_ieee1275_openfw.o grubof-fs_ext2.o grubof-fs_ufs.o grubof-fs_minix.o grubof-fs_hfs.o grubof-fs_jfs.o grubof-normal_cmdline.o grubof-normal_command.o grubof-normal_main.o grubof-normal_menu.o grubof-disk_powerpc_ieee1275_ofdisk.o grubof-disk_powerpc_ieee1275_partition.o grubof-kern_env.o grubof-normal_arg.o grubof-loader_powerpc_ieee1275_linux.o grubof-loader_powerpc_ieee1275_linux_normal.o grubof-commands_boot.o $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grubof_LDFLAGS) grubof-boot_powerpc_ieee1275_cmain.o: boot/powerpc/ieee1275/cmain.c @@ -495,6 +503,14 @@ grubof-fs_hfs.d: fs/hfs.c -include grubof-fs_hfs.d +grubof-fs_jfs.o: fs/jfs.c + $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -c -o $@ $< + +grubof-fs_jfs.d: fs/jfs.c + set -e; $(BUILD_CC) -Ifs -I$(srcdir)/fs $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -M $< | sed 's,jfs\.o[ :]*,grubof-fs_jfs.o $@ : ,g' > $@; [ -s $@ ] || rm -f $@ + +-include grubof-fs_jfs.d + grubof-normal_cmdline.o: normal/cmdline.c $(BUILD_CC) -Inormal -I$(srcdir)/normal $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grubof_CFLAGS) -c -o $@ $< diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 8f1e8a684..7086c0bef 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -26,7 +26,7 @@ grub_emu_SOURCES = kern/main.c kern/device.c \ kern/misc.c kern/loader.c kern/rescue.c kern/term.c \ disk/powerpc/ieee1275/partition.c \ util/i386/pc/biosdisk.c fs/fat.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ - normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ + fs/jfs.c normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ normal/arg.c \ util/console.c util/grub-emu.c util/misc.c util/i386/pc/getroot.c \ kern/env.c commands/ls.c \ @@ -39,7 +39,7 @@ grubof_SOURCES = boot/powerpc/ieee1275/cmain.c boot/powerpc/ieee1275/ieee1275.c kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ kern/powerpc/ieee1275/init.c term/powerpc/ieee1275/ofconsole.c \ kern/powerpc/ieee1275/openfw.c fs/ext2.c fs/ufs.c fs/minix.c fs/hfs.c \ - normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ + fs/jfs.c normal/cmdline.c normal/command.c normal/main.c normal/menu.c \ disk/powerpc/ieee1275/ofdisk.c disk/powerpc/ieee1275/partition.c \ kern/env.c normal/arg.c loader/powerpc/ieee1275/linux.c \ loader/powerpc/ieee1275/linux_normal.c commands/boot.c diff --git a/fs/fat.c b/fs/fat.c index 4ce269eb6..f2a89e7e9 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -304,68 +304,6 @@ grub_fat_mount (grub_disk_t disk) return 0; } -/* Convert UTF-16 (little endian) to UTF8. */ -static grub_uint8_t * -grub_fat_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 = grub_le_to_cpu16 (*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 >> 16) | 0xE0; - *dest++ = ((code >> 12) & 0x3F) | 0x80; - *dest++ = (code & 0x3F) | 0x80; - } - } - } - - return dest; -} - static grub_ssize_t grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, void (*read_hook) (unsigned long sector, @@ -610,7 +548,12 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, if (sum == checksum) { - *grub_fat_utf16_to_utf8 (filename, unibuf, slots * 13) = '\0'; + int u; + + for (u = 0; u < slots * 13; u++) + unibuf[u] = grub_le_to_cpu16 (unibuf[u]); + + *grub_utf16_to_utf8 (filename, unibuf, slots * 13) = '\0'; if (*dirname == '\0' && call_hook) { diff --git a/fs/jfs.c b/fs/jfs.c new file mode 100644 index 000000000..306d8c736 --- /dev/null +++ b/fs/jfs.c @@ -0,0 +1,892 @@ +/* jfs.c - JFS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004 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 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#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 + { + struct grub_jfs_treehead tree; + struct grub_jfs_tree_extent extents[16]; + } file __attribute__ ((packed)); + 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 (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); + 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 = 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 entrie 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 (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 (*read_hook) (unsigned long sector, + unsigned offset, unsigned length), + int pos, unsigned int 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 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++; + } + + 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, 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_ssize_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 (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 + }; + +#ifdef GRUB_UTIL +void +grub_jfs_init (void) +{ + grub_fs_register (&grub_jfs_fs); +} + +void +grub_jfs_fini (void) +{ + grub_fs_unregister (&grub_jfs_fs); +} +#else /* ! GRUB_UTIL */ +GRUB_MOD_INIT +{ + grub_fs_register (&grub_jfs_fs); + my_mod = mod; +} + +GRUB_MOD_FINI +{ + grub_fs_unregister (&grub_jfs_fs); +} +#endif /* ! GRUB_UTIL */ diff --git a/include/grub/fs.h b/include/grub/fs.h index a3cedf533..babe23a50 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -76,6 +76,8 @@ void grub_minix_init (void); void grub_minix_fini (void); void grub_hfs_init (void); void grub_hfs_fini (void); +void grub_jfs_init (void); +void grub_jfs_fini (void); #endif /* GRUB_UTIL */ #endif /* ! GRUB_FS_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h index 9d29a27a3..e7cbca3cd 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -58,6 +58,10 @@ 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_stop) (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_err_t EXPORT_FUNC(grub_split_cmdline) (const char *str, grub_err_t (* getline) (char **), int *argc, char ***argv); diff --git a/kern/misc.c b/kern/misc.c index bd88d243b..36604ac68 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -647,6 +647,68 @@ grub_sprintf (char *str, const char *fmt, ...) return ret; } +/* Convert UTF-16 to UTF8. */ +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 >> 16) | 0xE0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + + return dest; +} + grub_err_t grub_split_cmdline (const char *cmdline, grub_err_t (* getline) (char **), int *argc, char ***argv) { diff --git a/util/grub-emu.c b/util/grub-emu.c index 382775d21..60c5eadcd 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -161,6 +161,7 @@ main (int argc, char *argv[]) grub_ufs_init (); grub_minix_init (); grub_hfs_init (); + grub_jfs_init (); grub_ls_init (); grub_boot_init (); grub_cmp_init (); @@ -179,6 +180,7 @@ main (int argc, char *argv[]) grub_ext2_fini (); grub_minix_fini (); grub_hfs_fini (); + grub_jfs_fini (); grub_fat_fini (); grub_boot_fini (); grub_cmp_fini ();